blob: a4529e662fde439b19fc49cd6e81401607210d7f [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;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000652 touchedWindow.dispatchMode = InputTarget::DispatchMode::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
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000663 touchedWindow.dispatchMode = InputTarget::DispatchMode::HOVER_ENTER;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000664 } 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 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000677 touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000678 }
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);
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00001319 addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::OUTSIDE,
1320 ftl::Flags<InputTarget::Flags>(), pointerIds,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07001321 /*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 Vishniakouf1035d42019-09-20 16:32:01 +01001598 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001599 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1600 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001601 std::string reason = std::string("reason=").append(entry->reason);
1602 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001603 dispatchEventLocked(currentTime, entry, {target});
1604}
1605
Prabir Pradhan99987712020-11-10 18:43:05 -08001606void InputDispatcher::dispatchPointerCaptureChangedLocked(
Prabir Pradhan24047542023-11-02 17:14:59 +00001607 nsecs_t currentTime, const std::shared_ptr<const PointerCaptureChangedEntry>& entry,
Prabir Pradhan99987712020-11-10 18:43:05 -08001608 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001609 dropReason = DropReason::NOT_DROPPED;
1610
Prabir Pradhan99987712020-11-10 18:43:05 -08001611 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001612 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001613
1614 if (entry->pointerCaptureRequest.enable) {
1615 // Enable Pointer Capture.
1616 if (haveWindowWithPointerCapture &&
1617 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
Prabir Pradhan7092e262022-05-03 16:51:09 +00001618 // This can happen if pointer capture is disabled and re-enabled before we notify the
1619 // app of the state change, so there is no need to notify the app.
1620 ALOGI("Skipping dispatch of Pointer Capture being enabled: no state change.");
1621 return;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001622 }
1623 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001624 // This can happen if a window requests capture and immediately releases capture.
1625 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001626 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001627 return;
1628 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001629 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1630 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1631 return;
1632 }
1633
Vishnu Nairc519ff72021-01-21 08:23:08 -08001634 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001635 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1636 mWindowTokenWithPointerCapture = token;
1637 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001638 // Disable Pointer Capture.
1639 // We do not check if the sequence number matches for requests to disable Pointer Capture
1640 // for two reasons:
1641 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1642 // to disable capture with the same sequence number: one generated by
1643 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1644 // Capture being disabled in InputReader.
1645 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1646 // actual Pointer Capture state that affects events being generated by input devices is
1647 // in InputReader.
1648 if (!haveWindowWithPointerCapture) {
1649 // Pointer capture was already forcefully disabled because of focus change.
1650 dropReason = DropReason::NOT_DROPPED;
1651 return;
1652 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001653 token = mWindowTokenWithPointerCapture;
1654 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001655 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001656 setPointerCaptureLocked(false);
1657 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001658 }
1659
1660 auto channel = getInputChannelLocked(token);
1661 if (channel == nullptr) {
1662 // Window has gone away, clean up Pointer Capture state.
1663 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001664 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001665 setPointerCaptureLocked(false);
1666 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001667 return;
1668 }
1669 InputTarget target;
1670 target.inputChannel = channel;
Prabir Pradhan99987712020-11-10 18:43:05 -08001671 entry->dispatchInProgress = true;
1672 dispatchEventLocked(currentTime, entry, {target});
1673
1674 dropReason = DropReason::NOT_DROPPED;
1675}
1676
Prabir Pradhan24047542023-11-02 17:14:59 +00001677void InputDispatcher::dispatchTouchModeChangeLocked(
1678 nsecs_t currentTime, const std::shared_ptr<const TouchModeEntry>& entry) {
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001679 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Antonio Kantek15beb512022-06-13 22:35:41 +00001680 getWindowHandlesLocked(entry->displayId);
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001681 if (windowHandles.empty()) {
1682 return;
1683 }
1684 const std::vector<InputTarget> inputTargets =
1685 getInputTargetsFromWindowHandlesLocked(windowHandles);
1686 if (inputTargets.empty()) {
1687 return;
1688 }
1689 entry->dispatchInProgress = true;
1690 dispatchEventLocked(currentTime, entry, inputTargets);
1691}
1692
1693std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1694 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1695 std::vector<InputTarget> inputTargets;
1696 for (const sp<WindowInfoHandle>& handle : windowHandles) {
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001697 const sp<IBinder>& token = handle->getToken();
1698 if (token == nullptr) {
1699 continue;
1700 }
1701 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1702 if (channel == nullptr) {
1703 continue; // Window has gone away
1704 }
1705 InputTarget target;
1706 target.inputChannel = channel;
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001707 inputTargets.push_back(target);
1708 }
1709 return inputTargets;
1710}
1711
Prabir Pradhan24047542023-11-02 17:14:59 +00001712bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001713 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001714 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001715 if (!entry->dispatchInProgress) {
1716 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1717 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1718 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1719 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001720 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001721 // We have seen two identical key downs in a row which indicates that the device
1722 // driver is automatically generating key repeats itself. We take note of the
1723 // repeat here, but we disable our own next key repeat timer since it is clear that
1724 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001725 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1726 // Make sure we don't get key down from a different device. If a different
1727 // device Id has same key pressed down, the new device Id will replace the
1728 // current one to hold the key repeat with repeat count reset.
1729 // In the future when got a KEY_UP on the device id, drop it and do not
1730 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001731 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1732 resetKeyRepeatLocked();
Colin Cross5b799302022-10-18 21:52:41 -07001733 mKeyRepeatState.nextRepeatTime = LLONG_MAX; // don't generate repeats ourselves
Michael Wrightd02c5b62014-02-10 15:10:22 -08001734 } else {
1735 // Not a repeat. Save key down state in case we do see a repeat later.
1736 resetKeyRepeatLocked();
1737 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1738 }
1739 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001740 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1741 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001742 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan65613802023-02-22 23:36:58 +00001743 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001744 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1745 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001746 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001747 resetKeyRepeatLocked();
1748 }
1749
1750 if (entry->repeatCount == 1) {
1751 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1752 } else {
1753 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1754 }
1755
1756 entry->dispatchInProgress = true;
1757
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001758 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001759 }
1760
1761 // Handle case where the policy asked us to try again later last time.
Michael Wright5caf55a2022-11-24 22:31:42 +00001762 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001763 if (currentTime < entry->interceptKeyWakeupTime) {
1764 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1765 *nextWakeupTime = entry->interceptKeyWakeupTime;
1766 }
1767 return false; // wait until next wakeup
1768 }
Michael Wright5caf55a2022-11-24 22:31:42 +00001769 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001770 entry->interceptKeyWakeupTime = 0;
1771 }
1772
1773 // Give the policy a chance to intercept the key.
Michael Wright5caf55a2022-11-24 22:31:42 +00001774 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001775 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001776 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001777 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001778
1779 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1780 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1781 };
1782 postCommandLocked(std::move(command));
Josep del Riob3981622023-04-18 15:49:45 +00001783 // Poke user activity for keys not passed to user
1784 pokeUserActivityLocked(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001785 return false; // wait for the command to run
1786 } else {
Michael Wright5caf55a2022-11-24 22:31:42 +00001787 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001788 }
Michael Wright5caf55a2022-11-24 22:31:42 +00001789 } else if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001790 if (*dropReason == DropReason::NOT_DROPPED) {
1791 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001792 }
1793 }
1794
1795 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001796 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001797 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001798 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1799 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001800 mReporter->reportDroppedKey(entry->id);
Josep del Riob3981622023-04-18 15:49:45 +00001801 // Poke user activity for undispatched keys
1802 pokeUserActivityLocked(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001803 return true;
1804 }
1805
1806 // Identify targets.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001807 InputEventInjectionResult injectionResult;
1808 sp<WindowInfoHandle> focusedWindow =
1809 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime,
1810 /*byref*/ injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001811 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001812 return false;
1813 }
1814
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001815 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001816 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001817 return true;
1818 }
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001819 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
1820
1821 std::vector<InputTarget> inputTargets;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00001822 addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
1823 InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001824
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001825 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001826 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001827
1828 // Dispatch the key.
1829 dispatchEventLocked(currentTime, entry, inputTargets);
1830 return true;
1831}
1832
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001833void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001834 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1835 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1836 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1837 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1838 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1839 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1840 entry.metaState, entry.repeatCount, entry.downTime);
1841 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001842}
1843
Prabir Pradhancef936d2021-07-21 16:17:52 +00001844void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
Prabir Pradhan24047542023-11-02 17:14:59 +00001845 const std::shared_ptr<const SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001846 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001847 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1848 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1849 "source=0x%x, sensorType=%s",
1850 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001851 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001852 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001853 auto command = [this, entry]() REQUIRES(mLock) {
1854 scoped_unlock unlock(mLock);
1855
1856 if (entry->accuracyChanged) {
Prabir Pradhana41d2442023-04-20 21:30:40 +00001857 mPolicy.notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001858 }
Prabir Pradhana41d2442023-04-20 21:30:40 +00001859 mPolicy.notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1860 entry->hwTimestamp, entry->values);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001861 };
1862 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001863}
1864
1865bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001866 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1867 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001868 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001869 }
Chris Yef59a2f42020-10-16 12:55:26 -07001870 { // acquire lock
1871 std::scoped_lock _l(mLock);
1872
1873 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001874 std::shared_ptr<const EventEntry> entry = *it;
Chris Yef59a2f42020-10-16 12:55:26 -07001875 if (entry->type == EventEntry::Type::SENSOR) {
1876 it = mInboundQueue.erase(it);
1877 releaseInboundEventLocked(entry);
1878 }
1879 }
1880 }
1881 return true;
1882}
1883
Prabir Pradhan24047542023-11-02 17:14:59 +00001884bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime,
1885 std::shared_ptr<const MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001886 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001887 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001888 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001889 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001890 entry->dispatchInProgress = true;
1891
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001892 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001893 }
1894
1895 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001896 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001897 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001898 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1899 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001900 return true;
1901 }
1902
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001903 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001904
1905 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001906 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001907
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001908 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001909 if (isPointerEvent) {
1910 // Pointer event. (eg. touchscreen)
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00001911
1912 if (mDragState &&
1913 (entry->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN) {
1914 // If drag and drop ongoing and pointer down occur: pilfer drag window pointers
1915 pilferPointersLocked(mDragState->dragWindow->getToken());
1916 }
1917
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08001918 inputTargets =
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07001919 findTouchedWindowTargetsLocked(currentTime, *entry, /*byref*/ injectionResult);
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08001920 LOG_ALWAYS_FATAL_IF(injectionResult != InputEventInjectionResult::SUCCEEDED &&
1921 !inputTargets.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001922 } else {
1923 // Non touch event. (eg. trackball)
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001924 sp<WindowInfoHandle> focusedWindow =
1925 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime, injectionResult);
1926 if (injectionResult == InputEventInjectionResult::SUCCEEDED) {
1927 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00001928 addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
1929 InputTarget::Flags::FOREGROUND, getDownTime(*entry),
1930 inputTargets);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001931 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001932 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001933 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001934 return false;
1935 }
1936
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001937 setInjectionResult(*entry, injectionResult);
Prabir Pradhan5735a322022-04-11 17:23:34 +00001938 if (injectionResult == InputEventInjectionResult::TARGET_MISMATCH) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001939 return true;
1940 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001941 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001942 CancelationOptions::Mode mode(
1943 isPointerEvent ? CancelationOptions::Mode::CANCEL_POINTER_EVENTS
1944 : CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS);
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001945 CancelationOptions options(mode, "input event injection failed");
1946 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001947 return true;
1948 }
1949
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001950 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001951 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001952
1953 // Dispatch the motion.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001954 dispatchEventLocked(currentTime, entry, inputTargets);
1955 return true;
1956}
1957
chaviw98318de2021-05-19 16:45:23 -05001958void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
Arthur Hung54745652022-04-20 07:17:41 +00001959 bool isExiting, const int32_t rawX,
1960 const int32_t rawY) {
1961 const vec2 xy = windowHandle->getInfo()->transform.transform(vec2(rawX, rawY));
arthurhungb89ccb02020-12-30 16:19:01 +08001962 std::unique_ptr<DragEntry> dragEntry =
Arthur Hung54745652022-04-20 07:17:41 +00001963 std::make_unique<DragEntry>(mIdGenerator.nextId(), now(), windowHandle->getToken(),
1964 isExiting, xy.x, xy.y);
arthurhungb89ccb02020-12-30 16:19:01 +08001965
1966 enqueueInboundEventLocked(std::move(dragEntry));
1967}
1968
Prabir Pradhan24047542023-11-02 17:14:59 +00001969void InputDispatcher::dispatchDragLocked(nsecs_t currentTime,
1970 std::shared_ptr<const DragEntry> entry) {
arthurhungb89ccb02020-12-30 16:19:01 +08001971 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1972 if (channel == nullptr) {
1973 return; // Window has gone away
1974 }
1975 InputTarget target;
1976 target.inputChannel = channel;
arthurhungb89ccb02020-12-30 16:19:01 +08001977 entry->dispatchInProgress = true;
1978 dispatchEventLocked(currentTime, entry, {target});
1979}
1980
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001981void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001982 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08001983 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=%s, displayId=%" PRId32
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001984 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001985 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001986 "metaState=0x%x, buttonState=0x%x,"
1987 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08001988 prefix, entry.eventTime, entry.deviceId,
1989 inputEventSourceToString(entry.source).c_str(), entry.displayId, entry.policyFlags,
1990 MotionEvent::actionToString(entry.action).c_str(), entry.actionButton, entry.flags,
1991 entry.metaState, entry.buttonState, entry.edgeFlags, entry.xPrecision,
1992 entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001993
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07001994 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
Siarhei Vishniakou09a8fe42022-07-21 17:27:03 -07001995 ALOGD(" Pointer %d: id=%d, toolType=%s, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001996 "x=%f, y=%f, pressure=%f, size=%f, "
1997 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1998 "orientation=%f",
Siarhei Vishniakou09a8fe42022-07-21 17:27:03 -07001999 i, entry.pointerProperties[i].id,
2000 ftl::enum_string(entry.pointerProperties[i].toolType).c_str(),
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002001 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2002 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2003 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2004 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2005 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2006 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2007 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2008 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2009 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2010 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002011 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002012}
2013
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002014void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
Prabir Pradhan24047542023-11-02 17:14:59 +00002015 std::shared_ptr<const EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002016 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002017 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002018 if (DEBUG_DISPATCH_CYCLE) {
2019 ALOGD("dispatchEventToCurrentInputTargets");
2020 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002021
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00002022 processInteractionsLocked(*eventEntry, inputTargets);
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002023
Michael Wrightd02c5b62014-02-10 15:10:22 -08002024 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
2025
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002026 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002027
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002028 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002029 std::shared_ptr<Connection> connection =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002030 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002031 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002032 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002033 } else {
Siarhei Vishniakou31dd1552023-10-30 18:46:10 -07002034 if (DEBUG_DROPPED_EVENTS_VERBOSE) {
2035 LOG(INFO) << "Dropping event delivery to target with channel "
2036 << inputTarget.inputChannel->getName()
2037 << " because it is no longer registered with the input dispatcher.";
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002038 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002039 }
2040 }
2041}
2042
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002043void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002044 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
2045 // If the policy decides to close the app, we will get a channel removal event via
2046 // unregisterInputChannel, and will clean up the connection that way. We are already not
2047 // sending new pointers to the connection when it blocked, but focused events will continue to
2048 // pile up.
2049 ALOGW("Canceling events for %s because it is unresponsive",
2050 connection->inputChannel->getName().c_str());
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002051 if (connection->status == Connection::Status::NORMAL) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00002052 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002053 "application not responding");
2054 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002055 }
2056}
2057
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002058void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002059 if (DEBUG_FOCUS) {
2060 ALOGD("Resetting ANR timeouts.");
2061 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002062
2063 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002064 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07002065 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002066}
2067
Tiger Huang721e26f2018-07-24 22:26:19 +08002068/**
2069 * Get the display id that the given event should go to. If this event specifies a valid display id,
2070 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
2071 * Focused display is the display that the user most recently interacted with.
2072 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002073int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08002074 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002075 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002076 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002077 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2078 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002079 break;
2080 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002081 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002082 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2083 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002084 break;
2085 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002086 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002087 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002088 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002089 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07002090 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08002091 case EventEntry::Type::SENSOR:
2092 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08002093 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002094 return ADISPLAY_ID_NONE;
2095 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002096 }
2097 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
2098}
2099
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002100bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
2101 const char* focusedWindowName) {
2102 if (mAnrTracker.empty()) {
2103 // already processed all events that we waited for
2104 mKeyIsWaitingForEventsTimeout = std::nullopt;
2105 return false;
2106 }
2107
2108 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
2109 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002110 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002111 mKeyIsWaitingForEventsTimeout = currentTime +
2112 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
2113 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002114 return true;
2115 }
2116
2117 // We still have pending events, and already started the timer
2118 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
2119 return true; // Still waiting
2120 }
2121
2122 // Waited too long, and some connection still hasn't processed all motions
2123 // Just send the key to the focused window
2124 ALOGW("Dispatching key to %s even though there are other unprocessed events",
2125 focusedWindowName);
2126 mKeyIsWaitingForEventsTimeout = std::nullopt;
2127 return false;
2128}
2129
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002130sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked(
2131 nsecs_t currentTime, const EventEntry& entry, nsecs_t* nextWakeupTime,
2132 InputEventInjectionResult& outInjectionResult) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002133 std::string reason;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002134 outInjectionResult = InputEventInjectionResult::FAILED; // Default result
Michael Wrightd02c5b62014-02-10 15:10:22 -08002135
Tiger Huang721e26f2018-07-24 22:26:19 +08002136 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05002137 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07002138 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08002139 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
2140
Michael Wrightd02c5b62014-02-10 15:10:22 -08002141 // If there is no currently focused window and no focused application
2142 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002143 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
2144 ALOGI("Dropping %s event because there is no focused window or focused application in "
2145 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08002146 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002147 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002148 }
2149
Vishnu Nair062a8672021-09-03 16:07:44 -07002150 // Drop key events if requested by input feature
2151 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002152 return nullptr;
Vishnu Nair062a8672021-09-03 16:07:44 -07002153 }
2154
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002155 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
2156 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
2157 // start interacting with another application via touch (app switch). This code can be removed
2158 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
2159 // an app is expected to have a focused window.
2160 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
2161 if (!mNoFocusedWindowTimeoutTime.has_value()) {
2162 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05002163 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
2164 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
2165 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002166 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05002167 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002168 ALOGW("Waiting because no window has focus but %s may eventually add a "
2169 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05002170 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002171 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002172 outInjectionResult = InputEventInjectionResult::PENDING;
2173 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002174 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
2175 // Already raised ANR. Drop the event
2176 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08002177 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002178 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002179 } else {
2180 // Still waiting for the focused window
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002181 outInjectionResult = InputEventInjectionResult::PENDING;
2182 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002183 }
2184 }
2185
2186 // we have a valid, non-null focused window
2187 resetNoFocusedWindowTimeoutLocked();
2188
Prabir Pradhan5735a322022-04-11 17:23:34 +00002189 // Verify targeted injection.
2190 if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) {
2191 ALOGW("Dropping injected event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002192 outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
2193 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002194 }
2195
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002196 if (focusedWindowHandle->getInfo()->inputConfig.test(
2197 WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002198 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002199 outInjectionResult = InputEventInjectionResult::PENDING;
2200 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002201 }
2202
2203 // If the event is a key event, then we must wait for all previous events to
2204 // complete before delivering it because previous events may have the
2205 // side-effect of transferring focus to a different window and we want to
2206 // ensure that the following keys are sent to the new window.
2207 //
2208 // Suppose the user touches a button in a window then immediately presses "A".
2209 // If the button causes a pop-up window to appear then we want to ensure that
2210 // the "A" key is delivered to the new pop-up window. This is because users
2211 // often anticipate pending UI changes when typing on a keyboard.
2212 // To obtain this behavior, we must serialize key events with respect to all
2213 // prior input events.
2214 if (entry.type == EventEntry::Type::KEY) {
2215 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
2216 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002217 outInjectionResult = InputEventInjectionResult::PENDING;
2218 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002219 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002220 }
2221
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002222 outInjectionResult = InputEventInjectionResult::SUCCEEDED;
2223 return focusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002224}
2225
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002226/**
2227 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
2228 * that are currently unresponsive.
2229 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002230std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
2231 const std::vector<Monitor>& monitors) const {
2232 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002233 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002234 [this](const Monitor& monitor) REQUIRES(mLock) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002235 std::shared_ptr<Connection> connection =
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002236 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002237 if (connection == nullptr) {
2238 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002239 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002240 return false;
2241 }
2242 if (!connection->responsive) {
2243 ALOGW("Unresponsive monitor %s will not get the new gesture",
2244 connection->inputChannel->getName().c_str());
2245 return false;
2246 }
2247 return true;
2248 });
2249 return responsiveMonitors;
2250}
2251
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002252std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002253 nsecs_t currentTime, const MotionEntry& entry,
Siarhei Vishniakou4fe57392022-10-25 13:44:30 -07002254 InputEventInjectionResult& outInjectionResult) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002255 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002256
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002257 std::vector<InputTarget> targets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002258 // For security reasons, we defer updating the touch state until we are sure that
2259 // event injection will be allowed.
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002260 const int32_t displayId = entry.displayId;
2261 const int32_t action = entry.action;
Siarhei Vishniakoubf880522023-05-01 11:03:22 -07002262 const int32_t maskedAction = MotionEvent::getActionMasked(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002263
2264 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002265 outInjectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002266
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002267 // Copy current touch state into tempTouchState.
2268 // This state will be used to update mTouchStatesByDisplay at the end of this function.
2269 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07002270 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002271 TouchState tempTouchState;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002272 if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
2273 oldState = &(it->second);
Prabir Pradhane680f9b2022-02-04 04:24:00 -08002274 tempTouchState = *oldState;
Jeff Brownf086ddb2014-02-11 14:28:48 -08002275 }
2276
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002277 bool isSplit = shouldSplitTouch(tempTouchState, entry);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002278
2279 const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2280 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2281 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002282 // A DOWN could be generated from POINTER_DOWN if the initial pointers did not land into any
2283 // touchable windows.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002284 const bool wasDown = oldState != nullptr && oldState->isDown(entry.deviceId);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002285 const bool isDown = (maskedAction == AMOTION_EVENT_ACTION_DOWN) ||
2286 (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN && !wasDown);
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002287 const bool newGesture = isDown || maskedAction == AMOTION_EVENT_ACTION_SCROLL ||
2288 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2289 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE;
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002290 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Siarhei Vishniakou5cee1e32022-11-29 12:35:39 -08002291
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002292 if (newGesture) {
2293 isSplit = false;
Siarhei Vishniakouf372b812023-02-14 18:06:51 -08002294 }
2295
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002296 if (isDown && tempTouchState.hasHoveringPointers(entry.deviceId)) {
2297 // Compatibility behaviour: ACTION_DOWN causes HOVER_EXIT to get generated.
2298 tempTouchState.clearHoveringPointers(entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002299 }
2300
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002301 if (isHoverAction) {
Siarhei Vishniakou7be50c92023-11-17 17:09:08 -08002302 if (wasDown) {
2303 // Started hovering, but the device is already down: reject the hover event
2304 LOG(ERROR) << "Got hover event " << entry.getDescription()
2305 << " but the device is already down " << oldState->dump();
2306 outInjectionResult = InputEventInjectionResult::FAILED;
2307 return {};
2308 }
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002309 // For hover actions, we will treat 'tempTouchState' as a new state, so let's erase
2310 // all of the existing hovering pointers and recompute.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002311 tempTouchState.clearHoveringPointers(entry.deviceId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002312 }
2313
Michael Wrightd02c5b62014-02-10 15:10:22 -08002314 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2315 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07002316 const auto [x, y] = resolveTouchedPosition(entry);
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002317 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07002318 const int32_t pointerId = entry.pointerProperties[pointerIndex].id;
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002319 // Outside targets should be added upon first dispatched DOWN event. That means, this should
2320 // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down.
Prabir Pradhand65552b2021-10-07 11:23:50 -07002321 const bool isStylus = isPointerFromStylus(entry, pointerIndex);
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002322 sp<WindowInfoHandle> newTouchedWindowHandle =
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002323 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Michael Wright3dd60e22019-03-27 22:06:44 +00002324
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002325 if (isDown) {
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07002326 targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointerId);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002327 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002328 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002329 if (newTouchedWindowHandle == nullptr) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00002330 ALOGD("No new touched window at (%.1f, %.1f) in display %" PRId32, x, y, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002331 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002332 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002333 }
2334
Prabir Pradhan5735a322022-04-11 17:23:34 +00002335 // Verify targeted injection.
2336 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2337 ALOGW("Dropping injected touch event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002338 outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
Prabir Pradhan5735a322022-04-11 17:23:34 +00002339 newTouchedWindowHandle = nullptr;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002340 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002341 }
2342
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002343 // Figure out whether splitting will be allowed for this window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002344 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002345 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2346 // New window supports splitting, but we should never split mouse events.
2347 isSplit = !isFromMouse;
2348 } else if (isSplit) {
2349 // New window does not support splitting but we have already split events.
2350 // Ignore the new window.
Siarhei Vishniakou25537f82023-07-18 14:35:47 -07002351 LOG(INFO) << "Skipping " << newTouchedWindowHandle->getName()
2352 << " because it doesn't support split touch";
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002353 newTouchedWindowHandle = nullptr;
2354 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002355 } else {
2356 // No window is touched, so set split to true. This will allow the next pointer down to
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002357 // be delivered to a new window which supports split touch. Pointers from a mouse device
2358 // should never be split.
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002359 isSplit = !isFromMouse;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002360 }
2361
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002362 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002363 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002364 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002365 // Process the foreground window first so that it is the first to receive the event.
2366 newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002367 }
2368
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002369 if (newTouchedWindows.empty()) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00002370 ALOGI("Dropping event because there is no touchable window at (%.1f, %.1f) on display "
2371 "%d.",
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002372 x, y, displayId);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002373 outInjectionResult = InputEventInjectionResult::FAILED;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002374 return {};
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002375 }
2376
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002377 for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07002378 if (!canWindowReceiveMotionLocked(windowHandle, entry)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002379 continue;
2380 }
2381
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002382 if (isHoverAction) {
Siarhei Vishniakoub681c202023-05-01 11:22:33 -07002383 // The "windowHandle" is the target of this hovering pointer.
2384 tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointerId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002385 }
2386
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002387 // Set target flags.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002388 ftl::Flags<InputTarget::Flags> targetFlags;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002389
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002390 if (canReceiveForegroundTouches(*windowHandle->getInfo())) {
2391 // There should only be one touched window that can be "foreground" for the pointer.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002392 targetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002393 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002394
2395 if (isSplit) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002396 targetFlags |= InputTarget::Flags::SPLIT;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002397 }
2398 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002399 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002400 } else if (isWindowObscuredLocked(windowHandle)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002401 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002402 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002403
2404 // Update the temporary touch state.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002405
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002406 if (!isHoverAction) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002407 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07002408 pointerIds.set(pointerId);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002409 const bool isDownOrPointerDown = maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2410 maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002411 tempTouchState.addOrUpdateWindow(windowHandle, InputTarget::DispatchMode::AS_IS,
2412 targetFlags, entry.deviceId, pointerIds,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002413 isDownOrPointerDown
2414 ? std::make_optional(entry.eventTime)
2415 : std::nullopt);
2416 // If this is the pointer going down and the touched window has a wallpaper
2417 // then also add the touched wallpaper windows so they are locked in for the
2418 // duration of the touch gesture. We do not collect wallpapers during HOVER_MOVE or
2419 // SCROLL because the wallpaper engine only supports touch events. We would need to
2420 // add a mechanism similar to View.onGenericMotionEvent to enable wallpapers to
2421 // handle these events.
2422 if (isDownOrPointerDown && targetFlags.test(InputTarget::Flags::FOREGROUND) &&
Arthur Hungc539dbb2022-12-08 07:45:36 +00002423 windowHandle->getInfo()->inputConfig.test(
2424 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
2425 sp<WindowInfoHandle> wallpaper = findWallpaperWindowBelow(windowHandle);
2426 if (wallpaper != nullptr) {
2427 ftl::Flags<InputTarget::Flags> wallpaperFlags =
2428 InputTarget::Flags::WINDOW_IS_OBSCURED |
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002429 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Arthur Hungc539dbb2022-12-08 07:45:36 +00002430 if (isSplit) {
2431 wallpaperFlags |= InputTarget::Flags::SPLIT;
2432 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002433 tempTouchState.addOrUpdateWindow(wallpaper,
2434 InputTarget::DispatchMode::AS_IS,
2435 wallpaperFlags, entry.deviceId, pointerIds,
2436 entry.eventTime);
Arthur Hungc539dbb2022-12-08 07:45:36 +00002437 }
2438 }
2439 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002440 }
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00002441
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002442 // If a window is already pilfering some pointers, give it this new pointer as well and
2443 // make it pilfering. This will prevent other non-spy windows from getting this pointer,
2444 // which is a specific behaviour that we want.
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002445 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002446 if (touchedWindow.hasTouchingPointer(entry.deviceId, pointerId) &&
2447 touchedWindow.hasPilferingPointers(entry.deviceId)) {
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002448 // This window is already pilfering some pointers, and this new pointer is also
2449 // going to it. Therefore, take over this pointer and don't give it to anyone
2450 // else.
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002451 touchedWindow.addPilferingPointer(entry.deviceId, pointerId);
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00002452 }
2453 }
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002454
2455 // Restrict all pilfered pointers to the pilfering windows.
2456 tempTouchState.cancelPointersForNonPilferingWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002457 } else {
2458 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2459
2460 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002461 if (!tempTouchState.isDown(entry.deviceId) &&
2462 maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) {
Siarhei Vishniakou31dd1552023-10-30 18:46:10 -07002463 if (DEBUG_DROPPED_EVENTS_VERBOSE) {
2464 LOG(INFO) << "Dropping event because the pointer for device " << entry.deviceId
2465 << " is not down or we previously dropped the pointer down event in "
2466 << "display " << displayId << ": " << entry.getDescription();
2467 }
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002468 outInjectionResult = InputEventInjectionResult::FAILED;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002469 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002470 }
2471
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002472 // If the pointer is not currently hovering, then ignore the event.
2473 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2474 const int32_t pointerId = entry.pointerProperties[0].id;
2475 if (oldState == nullptr ||
2476 oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId).empty()) {
2477 LOG(INFO) << "Dropping event because the hovering pointer is not in any windows in "
2478 "display "
2479 << displayId << ": " << entry.getDescription();
2480 outInjectionResult = InputEventInjectionResult::FAILED;
2481 return {};
2482 }
2483 tempTouchState.removeHoveringPointer(entry.deviceId, pointerId);
2484 }
2485
arthurhung6d4bed92021-03-17 11:59:33 +08002486 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002487
Michael Wrightd02c5b62014-02-10 15:10:22 -08002488 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002489 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.getPointerCount() == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002490 tempTouchState.isSlippery()) {
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07002491 const auto [x, y] = resolveTouchedPosition(entry);
Harry Cutts33476232023-01-30 19:57:29 +00002492 const bool isStylus = isPointerFromStylus(entry, /*pointerIndex=*/0);
chaviw98318de2021-05-19 16:45:23 -05002493 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002494 tempTouchState.getFirstForegroundWindowHandle();
Siarhei Vishniakou0f6558d2023-04-21 12:05:13 -07002495 LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr);
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002496 sp<WindowInfoHandle> newTouchedWindowHandle =
2497 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Vishnu Nair062a8672021-09-03 16:07:44 -07002498
Prabir Pradhan5735a322022-04-11 17:23:34 +00002499 // Verify targeted injection.
2500 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2501 ALOGW("Dropping injected event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002502 outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002503 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002504 }
2505
Vishnu Nair062a8672021-09-03 16:07:44 -07002506 // Drop touch events if requested by input feature
2507 if (newTouchedWindowHandle != nullptr &&
2508 shouldDropInput(entry, newTouchedWindowHandle)) {
2509 newTouchedWindowHandle = nullptr;
2510 }
2511
Siarhei Vishniakouafa08cc2023-05-08 22:35:50 -07002512 if (newTouchedWindowHandle != nullptr &&
2513 !haveSameToken(oldTouchedWindowHandle, newTouchedWindowHandle)) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002514 ALOGI("Touch is slipping out of window %s into window %s in display %" PRId32,
Siarhei Vishniakou0f6558d2023-04-21 12:05:13 -07002515 oldTouchedWindowHandle->getName().c_str(),
2516 newTouchedWindowHandle->getName().c_str(), displayId);
2517
Michael Wrightd02c5b62014-02-10 15:10:22 -08002518 // Make a slippery exit from the old window.
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08002519 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002520 const int32_t pointerId = entry.pointerProperties[0].id;
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08002521 pointerIds.set(pointerId);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002522
2523 const TouchedWindow& touchedWindow =
2524 tempTouchState.getTouchedWindow(oldTouchedWindowHandle);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002525 addPointerWindowTargetLocked(oldTouchedWindowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002526 InputTarget::DispatchMode::SLIPPERY_EXIT,
2527 ftl::Flags<InputTarget::Flags>(), pointerIds,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002528 touchedWindow.getDownTimeInTarget(entry.deviceId),
2529 targets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002530
2531 // Make a slippery entrance into the new window.
2532 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002533 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002534 }
2535
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002536 ftl::Flags<InputTarget::Flags> targetFlags;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002537 if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002538 targetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002539 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002540 if (isSplit) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002541 targetFlags |= InputTarget::Flags::SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002542 }
2543 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002544 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002545 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002546 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002547 }
2548
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002549 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle,
2550 InputTarget::DispatchMode::SLIPPERY_ENTER,
2551 targetFlags, entry.deviceId, pointerIds,
2552 entry.eventTime);
Arthur Hungc539dbb2022-12-08 07:45:36 +00002553
2554 // Check if the wallpaper window should deliver the corresponding event.
2555 slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002556 tempTouchState, entry.deviceId, pointerId, targets);
2557 tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointerId,
2558 oldTouchedWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002559 }
2560 }
Arthur Hung96483742022-11-15 03:30:48 +00002561
2562 // Update the pointerIds for non-splittable when it received pointer down.
2563 if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2564 // If no split, we suppose all touched windows should receive pointer down.
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002565 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
Arthur Hung96483742022-11-15 03:30:48 +00002566 for (size_t i = 0; i < tempTouchState.windows.size(); i++) {
2567 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2568 // Ignore drag window for it should just track one pointer.
2569 if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
2570 continue;
2571 }
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002572 std::bitset<MAX_POINTER_ID + 1> touchingPointers;
2573 touchingPointers.set(entry.pointerProperties[pointerIndex].id);
2574 touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers);
Arthur Hung96483742022-11-15 03:30:48 +00002575 }
2576 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002577 }
2578
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002579 // Update dispatching for hover enter and exit.
Sam Dubeyf886dec2023-01-27 13:28:19 +00002580 {
2581 std::vector<TouchedWindow> hoveringWindows =
2582 getHoveringWindowsLocked(oldState, tempTouchState, entry);
2583 for (const TouchedWindow& touchedWindow : hoveringWindows) {
Siarhei Vishniakoud5876ba2023-05-15 17:58:34 -07002584 std::optional<InputTarget> target =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002585 createInputTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
2586 touchedWindow.targetFlags,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002587 touchedWindow.getDownTimeInTarget(entry.deviceId));
Siarhei Vishniakoud5876ba2023-05-15 17:58:34 -07002588 if (!target) {
2589 continue;
2590 }
2591 // Hardcode to single hovering pointer for now.
2592 std::bitset<MAX_POINTER_ID + 1> pointerIds;
2593 pointerIds.set(entry.pointerProperties[0].id);
2594 target->addPointers(pointerIds, touchedWindow.windowHandle->getInfo()->transform);
2595 targets.push_back(*target);
Sam Dubeyf886dec2023-01-27 13:28:19 +00002596 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002597 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002598
Prabir Pradhan5735a322022-04-11 17:23:34 +00002599 // Ensure that all touched windows are valid for injection.
2600 if (entry.injectionState != nullptr) {
2601 std::string errs;
2602 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Prabir Pradhan5735a322022-04-11 17:23:34 +00002603 const auto err = verifyTargetedInjection(touchedWindow.windowHandle, entry);
2604 if (err) errs += "\n - " + *err;
2605 }
2606 if (!errs.empty()) {
2607 ALOGW("Dropping targeted injection: At least one touched window is not owned by uid "
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00002608 "%s:%s",
2609 entry.injectionState->targetUid->toString().c_str(), errs.c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002610 outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002611 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002612 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002613 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002614
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002615 // Check whether windows listening for outside touches are owned by the same UID. If the owner
2616 // has a different UID, then we will not reveal coordinate information to this window.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002617 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002618 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002619 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002620 if (foregroundWindowHandle) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00002621 const auto foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002622 for (InputTarget& target : targets) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002623 if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002624 sp<WindowInfoHandle> targetWindow =
2625 getWindowHandleLocked(target.inputChannel->getConnectionToken());
2626 if (targetWindow->getInfo()->ownerUid != foregroundWindowUid) {
2627 target.flags |= InputTarget::Flags::ZERO_COORDS;
Michael Wright3dd60e22019-03-27 22:06:44 +00002628 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002629 }
2630 }
2631 }
2632 }
2633
Harry Cuttsb166c002023-05-09 13:06:05 +00002634 // If this is a touchpad navigation gesture, it needs to only be sent to trusted targets, as we
2635 // only want the system UI to handle these gestures.
2636 const bool isTouchpadNavGesture = isFromSource(entry.source, AINPUT_SOURCE_MOUSE) &&
2637 entry.classification == MotionClassification::MULTI_FINGER_SWIPE;
2638 if (isTouchpadNavGesture) {
2639 filterUntrustedTargets(/* byref */ tempTouchState, /* byref */ targets);
2640 }
2641
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002642 // Output targets from the touch state.
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002643 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002644 std::bitset<MAX_POINTER_ID + 1> touchingPointers =
2645 touchedWindow.getTouchingPointers(entry.deviceId);
2646 if (touchingPointers.none()) {
Siarhei Vishniakoue0431e42023-01-28 17:01:39 -08002647 continue;
2648 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002649 addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
2650 touchedWindow.targetFlags, touchingPointers,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002651 touchedWindow.getDownTimeInTarget(entry.deviceId), targets);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002652 }
Sam Dubey39d37cf2022-12-07 18:05:35 +00002653
Siarhei Vishniakou580fb3a2023-05-05 15:02:20 -07002654 // During targeted injection, only allow owned targets to receive events
2655 std::erase_if(targets, [&](const InputTarget& target) {
2656 LOG_ALWAYS_FATAL_IF(target.windowHandle == nullptr);
2657 const auto err = verifyTargetedInjection(target.windowHandle, entry);
2658 if (err) {
2659 LOG(WARNING) << "Dropping injected event from " << target.windowHandle->getName()
2660 << ": " << (*err);
2661 return true;
2662 }
2663 return false;
2664 });
2665
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002666 if (targets.empty()) {
2667 LOG(INFO) << "Dropping event because no targets were found: " << entry.getDescription();
2668 outInjectionResult = InputEventInjectionResult::FAILED;
2669 return {};
2670 }
2671
2672 // If we only have windows getting ACTION_OUTSIDE, then drop the event, because there is no
2673 // window that is actually receiving the entire gesture.
2674 if (std::all_of(targets.begin(), targets.end(), [](const InputTarget& target) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002675 return target.dispatchMode == InputTarget::DispatchMode::OUTSIDE;
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002676 })) {
2677 LOG(INFO) << "Dropping event because all windows would just receive ACTION_OUTSIDE: "
2678 << entry.getDescription();
2679 outInjectionResult = InputEventInjectionResult::FAILED;
2680 return {};
2681 }
2682
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002683 outInjectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002684
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002685 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
2686 // Targets that we entered in a slippery way will now become AS-IS targets
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002687 if (touchedWindow.dispatchMode == InputTarget::DispatchMode::SLIPPERY_ENTER) {
2688 touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002689 }
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002690 }
2691
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002692 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou7be50c92023-11-17 17:09:08 -08002693 if (maskedAction == AMOTION_EVENT_ACTION_UP) {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002694 // Pointer went up.
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002695 tempTouchState.removeTouchingPointer(entry.deviceId, entry.pointerProperties[0].id);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002696 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002697 // All pointers up or canceled.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002698 tempTouchState.removeAllPointersForDevice(entry.deviceId);
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002699 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2700 // One pointer went up.
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002701 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
2702 const uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
2703 tempTouchState.removeTouchingPointer(entry.deviceId, pointerId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002704 }
2705
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002706 // Save changes unless the action was scroll in which case the temporary touch
2707 // state was only valid for this one action.
2708 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07002709 if (displayId >= 0) {
Siarhei Vishniakouf372b812023-02-14 18:06:51 -08002710 tempTouchState.clearWindowsWithoutPointers();
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002711 mTouchStatesByDisplay[displayId] = tempTouchState;
2712 } else {
2713 mTouchStatesByDisplay.erase(displayId);
2714 }
2715 }
2716
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08002717 if (tempTouchState.windows.empty()) {
2718 mTouchStatesByDisplay.erase(displayId);
2719 }
2720
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002721 return targets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002722}
2723
arthurhung6d4bed92021-03-17 11:59:33 +08002724void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07002725 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2726 // have an explicit reason to support it.
2727 constexpr bool isStylus = false;
2728
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002729 sp<WindowInfoHandle> dropWindow =
Harry Cutts33476232023-01-30 19:57:29 +00002730 findTouchedWindowAtLocked(displayId, x, y, isStylus, /*ignoreDragWindow=*/true);
arthurhung6d4bed92021-03-17 11:59:33 +08002731 if (dropWindow) {
2732 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002733 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002734 } else {
Arthur Hung54745652022-04-20 07:17:41 +00002735 ALOGW("No window found when drop.");
Prabir Pradhancef936d2021-07-21 16:17:52 +00002736 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002737 }
2738 mDragState.reset();
2739}
2740
2741void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
Arthur Hung3915c1f2022-05-31 07:17:17 +00002742 if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId) {
arthurhungb89ccb02020-12-30 16:19:01 +08002743 return;
2744 }
2745
arthurhung6d4bed92021-03-17 11:59:33 +08002746 if (!mDragState->isStartDrag) {
2747 mDragState->isStartDrag = true;
2748 mDragState->isStylusButtonDownAtStart =
2749 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2750 }
2751
Arthur Hung54745652022-04-20 07:17:41 +00002752 // Find the pointer index by id.
2753 int32_t pointerIndex = 0;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002754 for (; static_cast<uint32_t>(pointerIndex) < entry.getPointerCount(); pointerIndex++) {
Arthur Hung54745652022-04-20 07:17:41 +00002755 const PointerProperties& pointerProperties = entry.pointerProperties[pointerIndex];
2756 if (pointerProperties.id == mDragState->pointerId) {
2757 break;
arthurhung6d4bed92021-03-17 11:59:33 +08002758 }
Arthur Hung54745652022-04-20 07:17:41 +00002759 }
arthurhung6d4bed92021-03-17 11:59:33 +08002760
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002761 if (uint32_t(pointerIndex) == entry.getPointerCount()) {
Arthur Hung54745652022-04-20 07:17:41 +00002762 LOG_ALWAYS_FATAL("Should find a valid pointer index by id %d", mDragState->pointerId);
Arthur Hung54745652022-04-20 07:17:41 +00002763 }
2764
2765 const int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2766 const int32_t x = entry.pointerCoords[pointerIndex].getX();
2767 const int32_t y = entry.pointerCoords[pointerIndex].getY();
2768
2769 switch (maskedAction) {
2770 case AMOTION_EVENT_ACTION_MOVE: {
2771 // Handle the special case : stylus button no longer pressed.
2772 bool isStylusButtonDown =
2773 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2774 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2775 finishDragAndDrop(entry.displayId, x, y);
2776 return;
2777 }
2778
2779 // Prevent stylus interceptor windows from affecting drag and drop behavior for now,
2780 // until we have an explicit reason to support it.
2781 constexpr bool isStylus = false;
2782
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002783 sp<WindowInfoHandle> hoverWindowHandle =
2784 findTouchedWindowAtLocked(entry.displayId, x, y, isStylus,
2785 /*ignoreDragWindow=*/true);
Arthur Hung54745652022-04-20 07:17:41 +00002786 // enqueue drag exit if needed.
2787 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2788 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2789 if (mDragState->dragHoverWindowHandle != nullptr) {
Harry Cutts33476232023-01-30 19:57:29 +00002790 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, /*isExiting=*/true, x,
Arthur Hung54745652022-04-20 07:17:41 +00002791 y);
2792 }
2793 mDragState->dragHoverWindowHandle = hoverWindowHandle;
2794 }
2795 // enqueue drag location if needed.
2796 if (hoverWindowHandle != nullptr) {
Harry Cutts33476232023-01-30 19:57:29 +00002797 enqueueDragEventLocked(hoverWindowHandle, /*isExiting=*/false, x, y);
Arthur Hung54745652022-04-20 07:17:41 +00002798 }
2799 break;
2800 }
2801
2802 case AMOTION_EVENT_ACTION_POINTER_UP:
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002803 if (MotionEvent::getActionIndex(entry.action) != pointerIndex) {
Arthur Hung54745652022-04-20 07:17:41 +00002804 break;
2805 }
2806 // The drag pointer is up.
2807 [[fallthrough]];
2808 case AMOTION_EVENT_ACTION_UP:
2809 finishDragAndDrop(entry.displayId, x, y);
2810 break;
2811 case AMOTION_EVENT_ACTION_CANCEL: {
2812 ALOGD("Receiving cancel when drag and drop.");
2813 sendDropWindowCommandLocked(nullptr, 0, 0);
2814 mDragState.reset();
2815 break;
2816 }
arthurhungb89ccb02020-12-30 16:19:01 +08002817 }
2818}
2819
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002820std::optional<InputTarget> InputDispatcher::createInputTargetLocked(
2821 const sp<android::gui::WindowInfoHandle>& windowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002822 InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002823 std::optional<nsecs_t> firstDownTimeInTarget) const {
2824 std::shared_ptr<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
2825 if (inputChannel == nullptr) {
2826 ALOGW("Not creating InputTarget for %s, no input channel", windowHandle->getName().c_str());
2827 return {};
2828 }
2829 InputTarget inputTarget;
2830 inputTarget.inputChannel = inputChannel;
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00002831 inputTarget.windowHandle = windowHandle;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002832 inputTarget.dispatchMode = dispatchMode;
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002833 inputTarget.flags = targetFlags;
2834 inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor;
2835 inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
2836 const auto& displayInfoIt = mDisplayInfos.find(windowHandle->getInfo()->displayId);
2837 if (displayInfoIt != mDisplayInfos.end()) {
2838 inputTarget.displayTransform = displayInfoIt->second.transform;
2839 } else {
Siarhei Vishniakou580fb3a2023-05-05 15:02:20 -07002840 // DisplayInfo not found for this window on display windowHandle->getInfo()->displayId.
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002841 // TODO(b/198444055): Make this an error message after 'setInputWindows' API is removed.
2842 }
2843 return inputTarget;
2844}
2845
chaviw98318de2021-05-19 16:45:23 -05002846void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002847 InputTarget::DispatchMode dispatchMode,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002848 ftl::Flags<InputTarget::Flags> targetFlags,
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002849 std::optional<nsecs_t> firstDownTimeInTarget,
Siarhei Vishniakouf75cddb2022-10-25 10:42:16 -07002850 std::vector<InputTarget>& inputTargets) const {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002851 std::vector<InputTarget>::iterator it =
2852 std::find_if(inputTargets.begin(), inputTargets.end(),
2853 [&windowHandle](const InputTarget& inputTarget) {
2854 return inputTarget.inputChannel->getConnectionToken() ==
2855 windowHandle->getToken();
2856 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002857
chaviw98318de2021-05-19 16:45:23 -05002858 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002859
2860 if (it == inputTargets.end()) {
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002861 std::optional<InputTarget> target =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002862 createInputTargetLocked(windowHandle, dispatchMode, targetFlags,
2863 firstDownTimeInTarget);
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002864 if (!target) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002865 return;
2866 }
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002867 inputTargets.push_back(*target);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002868 it = inputTargets.end() - 1;
2869 }
2870
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002871 if (it->flags != targetFlags) {
2872 LOG(ERROR) << "Flags don't match! targetFlags=" << targetFlags.string() << ", it=" << *it;
2873 }
2874 if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
2875 LOG(ERROR) << "Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
2876 << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
2877 }
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002878}
2879
2880void InputDispatcher::addPointerWindowTargetLocked(
2881 const sp<android::gui::WindowInfoHandle>& windowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002882 InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
2883 std::bitset<MAX_POINTER_ID + 1> pointerIds, std::optional<nsecs_t> firstDownTimeInTarget,
2884 std::vector<InputTarget>& inputTargets) const REQUIRES(mLock) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002885 if (pointerIds.none()) {
2886 for (const auto& target : inputTargets) {
2887 LOG(INFO) << "Target: " << target;
2888 }
2889 LOG(FATAL) << "No pointers specified for " << windowHandle->getName();
2890 return;
2891 }
2892 std::vector<InputTarget>::iterator it =
2893 std::find_if(inputTargets.begin(), inputTargets.end(),
2894 [&windowHandle](const InputTarget& inputTarget) {
2895 return inputTarget.inputChannel->getConnectionToken() ==
2896 windowHandle->getToken();
2897 });
2898
2899 // This is a hack, because the actual entry could potentially be an ACTION_DOWN event that
2900 // causes a HOVER_EXIT to be generated. That means that the same entry of ACTION_DOWN would
2901 // have DISPATCH_AS_HOVER_EXIT and DISPATCH_AS_IS. And therefore, we have to create separate
2902 // input targets for hovering pointers and for touching pointers.
2903 // If we picked an existing input target above, but it's for HOVER_EXIT - let's use a new
2904 // target instead.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002905 if (it != inputTargets.end() && it->dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002906 // Force the code below to create a new input target
2907 it = inputTargets.end();
2908 }
2909
2910 const WindowInfo* windowInfo = windowHandle->getInfo();
2911
2912 if (it == inputTargets.end()) {
2913 std::optional<InputTarget> target =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002914 createInputTargetLocked(windowHandle, dispatchMode, targetFlags,
2915 firstDownTimeInTarget);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002916 if (!target) {
2917 return;
2918 }
2919 inputTargets.push_back(*target);
2920 it = inputTargets.end() - 1;
2921 }
2922
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002923 if (it->dispatchMode != dispatchMode) {
2924 LOG(ERROR) << __func__ << ": DispatchMode doesn't match! ignoring new mode="
2925 << ftl::enum_string(dispatchMode) << ", it=" << *it;
2926 }
Siarhei Vishniakou4bd0b7c2023-10-27 00:51:14 -07002927 if (it->flags != targetFlags) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002928 LOG(ERROR) << __func__ << ": Flags don't match! new targetFlags=" << targetFlags.string()
2929 << ", it=" << *it;
Siarhei Vishniakou4bd0b7c2023-10-27 00:51:14 -07002930 }
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002931 if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002932 LOG(ERROR) << __func__ << ": Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002933 << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
2934 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002935
chaviw1ff3d1e2020-07-01 15:53:47 -07002936 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002937}
2938
Michael Wright3dd60e22019-03-27 22:06:44 +00002939void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002940 int32_t displayId) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002941 auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
2942 if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
Michael Wright3dd60e22019-03-27 22:06:44 +00002943
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002944 for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
2945 InputTarget target;
2946 target.inputChannel = monitor.inputChannel;
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002947 // target.firstDownTimeInTarget is not set for global monitors. It is only required in split
2948 // touch and global monitoring works as intended even without setting firstDownTimeInTarget
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002949 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
2950 target.displayTransform = it->second.transform;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002951 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002952 target.setDefaultPointerTransform(target.displayTransform);
2953 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002954 }
2955}
2956
Robert Carrc9bf1d32020-04-13 17:21:08 -07002957/**
2958 * Indicate whether one window handle should be considered as obscuring
2959 * another window handle. We only check a few preconditions. Actually
2960 * checking the bounds is left to the caller.
2961 */
chaviw98318de2021-05-19 16:45:23 -05002962static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2963 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002964 // Compare by token so cloned layers aren't counted
2965 if (haveSameToken(windowHandle, otherHandle)) {
2966 return false;
2967 }
2968 auto info = windowHandle->getInfo();
2969 auto otherInfo = otherHandle->getInfo();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002970 if (otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002971 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002972 } else if (otherInfo->alpha == 0 &&
2973 otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002974 // Those act as if they were invisible, so we don't need to flag them.
2975 // We do want to potentially flag touchable windows even if they have 0
2976 // opacity, since they can consume touches and alter the effects of the
2977 // user interaction (eg. apps that rely on
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002978 // Flags::WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002979 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2980 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002981 } else if (info->ownerUid == otherInfo->ownerUid) {
2982 // If ownerUid is the same we don't generate occlusion events as there
2983 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002984 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002985 } else if (otherInfo->inputConfig.test(gui::WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002986 return false;
2987 } else if (otherInfo->displayId != info->displayId) {
2988 return false;
2989 }
2990 return true;
2991}
2992
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002993/**
2994 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2995 * untrusted, one should check:
2996 *
2997 * 1. If result.hasBlockingOcclusion is true.
2998 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2999 * BLOCK_UNTRUSTED.
3000 *
3001 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
3002 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
3003 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
3004 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
3005 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
3006 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
3007 *
3008 * If neither of those is true, then it means the touch can be allowed.
3009 */
3010InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05003011 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
3012 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003013 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05003014 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003015 TouchOcclusionInfo info;
3016 info.hasBlockingOcclusion = false;
3017 info.obscuringOpacity = 0;
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003018 info.obscuringUid = gui::Uid::INVALID;
3019 std::map<gui::Uid, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05003020 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003021 if (windowHandle == otherHandle) {
3022 break; // All future windows are below us. Exit early.
3023 }
chaviw98318de2021-05-19 16:45:23 -05003024 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00003025 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
3026 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003027 if (DEBUG_TOUCH_OCCLUSION) {
3028 info.debugInfo.push_back(
Harry Cutts101ee9b2023-07-06 18:04:14 +00003029 dumpWindowForTouchOcclusion(otherInfo, /*isTouchedWindow=*/false));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003030 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003031 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
3032 // we perform the checks below to see if the touch can be propagated or not based on the
3033 // window's touch occlusion mode
3034 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
3035 info.hasBlockingOcclusion = true;
3036 info.obscuringUid = otherInfo->ownerUid;
3037 info.obscuringPackage = otherInfo->packageName;
3038 break;
3039 }
3040 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003041 const auto uid = otherInfo->ownerUid;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003042 float opacity =
3043 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
3044 // Given windows A and B:
3045 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
3046 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
3047 opacityByUid[uid] = opacity;
3048 if (opacity > info.obscuringOpacity) {
3049 info.obscuringOpacity = opacity;
3050 info.obscuringUid = uid;
3051 info.obscuringPackage = otherInfo->packageName;
3052 }
3053 }
3054 }
3055 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003056 if (DEBUG_TOUCH_OCCLUSION) {
Harry Cutts101ee9b2023-07-06 18:04:14 +00003057 info.debugInfo.push_back(dumpWindowForTouchOcclusion(windowInfo, /*isTouchedWindow=*/true));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003058 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003059 return info;
3060}
3061
chaviw98318de2021-05-19 16:45:23 -05003062std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003063 bool isTouchedWindow) const {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003064 return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
Prabir Pradhan51e7db02022-02-07 06:02:57 -08003065 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
3066 "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
3067 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08003068 isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003069 info->ownerUid.toString().c_str(), info->id,
Chavi Weingarten7f019192023-08-08 20:39:01 +00003070 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frame.left,
3071 info->frame.top, info->frame.right, info->frame.bottom,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003072 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
3073 info->inputConfig.string().c_str(), toString(info->token != nullptr),
3074 info->applicationInfo.name.c_str(),
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07003075 binderToString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003076}
3077
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003078bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
3079 if (occlusionInfo.hasBlockingOcclusion) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003080 ALOGW("Untrusted touch due to occlusion by %s/%s", occlusionInfo.obscuringPackage.c_str(),
3081 occlusionInfo.obscuringUid.toString().c_str());
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003082 return false;
3083 }
3084 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003085 ALOGW("Untrusted touch due to occlusion by %s/%s (obscuring opacity = "
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003086 "%.2f, maximum allowed = %.2f)",
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003087 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid.toString().c_str(),
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003088 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
3089 return false;
3090 }
3091 return true;
3092}
3093
chaviw98318de2021-05-19 16:45:23 -05003094bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003095 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003096 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05003097 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3098 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07003099 if (windowHandle == otherHandle) {
3100 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08003101 }
chaviw98318de2021-05-19 16:45:23 -05003102 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07003103 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08003104 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003105 return true;
3106 }
3107 }
3108 return false;
3109}
3110
chaviw98318de2021-05-19 16:45:23 -05003111bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003112 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05003113 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3114 const WindowInfo* windowInfo = windowHandle->getInfo();
3115 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07003116 if (windowHandle == otherHandle) {
3117 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003118 }
chaviw98318de2021-05-19 16:45:23 -05003119 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07003120 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08003121 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003122 return true;
3123 }
3124 }
3125 return false;
3126}
3127
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003128std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05003129 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003130 if (applicationHandle != nullptr) {
3131 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07003132 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003133 } else {
3134 return applicationHandle->getName();
3135 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003136 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07003137 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003138 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003139 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003140 }
3141}
3142
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003143void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00003144 if (!isUserActivityEvent(eventEntry)) {
3145 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003146 return;
3147 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003148 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05003149 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Josep del Riob3981622023-04-18 15:49:45 +00003150 const WindowInfo* windowDisablingUserActivityInfo = nullptr;
Tiger Huang721e26f2018-07-24 22:26:19 +08003151 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003152 const WindowInfo* info = focusedWindowHandle->getInfo();
Prabir Pradhan51e7db02022-02-07 06:02:57 -08003153 if (info->inputConfig.test(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY)) {
Josep del Riob3981622023-04-18 15:49:45 +00003154 windowDisablingUserActivityInfo = info;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003155 }
3156 }
3157
3158 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003159 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003160 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003161 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3162 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003163 return;
3164 }
Josep del Riob3981622023-04-18 15:49:45 +00003165 if (windowDisablingUserActivityInfo != nullptr) {
3166 if (DEBUG_DISPATCH_CYCLE) {
3167 ALOGD("Not poking user activity: disabled by window '%s'.",
3168 windowDisablingUserActivityInfo->name.c_str());
3169 }
3170 return;
3171 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003172 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003173 eventType = USER_ACTIVITY_EVENT_TOUCH;
3174 }
3175 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003176 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003177 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003178 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3179 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003180 return;
3181 }
Josep del Riob3981622023-04-18 15:49:45 +00003182 // If the key code is unknown, we don't consider it user activity
3183 if (keyEntry.keyCode == AKEYCODE_UNKNOWN) {
3184 return;
3185 }
3186 // Don't inhibit events that were intercepted or are not passed to
3187 // the apps, like system shortcuts
3188 if (windowDisablingUserActivityInfo != nullptr &&
3189 keyEntry.interceptKeyResult != KeyEntry::InterceptKeyResult::SKIP &&
3190 keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER) {
3191 if (DEBUG_DISPATCH_CYCLE) {
3192 ALOGD("Not poking user activity: disabled by window '%s'.",
3193 windowDisablingUserActivityInfo->name.c_str());
3194 }
3195 return;
3196 }
3197
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003198 eventType = USER_ACTIVITY_EVENT_BUTTON;
3199 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003200 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00003201 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003202 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08003203 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003204 break;
3205 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003206 }
3207
Prabir Pradhancef936d2021-07-21 16:17:52 +00003208 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
3209 REQUIRES(mLock) {
3210 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003211 mPolicy.pokeUserActivity(eventTime, eventType, displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00003212 };
3213 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003214}
3215
3216void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003217 const std::shared_ptr<Connection>& connection,
Prabir Pradhan24047542023-11-02 17:14:59 +00003218 std::shared_ptr<const EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003219 const InputTarget& inputTarget) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003220 ATRACE_NAME_IF(ATRACE_ENABLED(),
3221 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
3222 connection->getInputChannelName().c_str(), eventEntry->id));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003223 if (DEBUG_DISPATCH_CYCLE) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003224 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=%s, "
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08003225 "globalScaleFactor=%f, pointerIds=%s %s",
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003226 connection->getInputChannelName().c_str(), inputTarget.flags.string().c_str(),
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08003227 inputTarget.globalScaleFactor, bitsetToString(inputTarget.pointerIds).c_str(),
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003228 inputTarget.getPointerInfoString().c_str());
3229 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003230
3231 // Skip this event if the connection status is not normal.
3232 // We don't want to enqueue additional outbound events if the connection is broken.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003233 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003234 if (DEBUG_DISPATCH_CYCLE) {
3235 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003236 connection->getInputChannelName().c_str(),
3237 ftl::enum_string(connection->status).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003238 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003239 return;
3240 }
3241
3242 // Split a motion event if needed.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003243 if (inputTarget.flags.test(InputTarget::Flags::SPLIT)) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003244 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003245 "Entry type %s should not have Flags::SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08003246 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003247
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003248 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003249 if (inputTarget.pointerIds.count() != originalMotionEntry.getPointerCount()) {
Siarhei Vishniakou16e4fa02023-02-16 17:48:56 -08003250 if (!inputTarget.firstDownTimeInTarget.has_value()) {
3251 logDispatchStateLocked();
3252 LOG(FATAL) << "Splitting motion events requires a down time to be set for the "
3253 "target on connection "
3254 << connection->getInputChannelName() << " for "
3255 << originalMotionEntry.getDescription();
3256 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003257 std::unique_ptr<MotionEntry> splitMotionEntry =
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00003258 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds,
3259 inputTarget.firstDownTimeInTarget.value());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003260 if (!splitMotionEntry) {
3261 return; // split event was dropped
3262 }
Arthur Hungb3307ee2021-10-14 10:57:37 +00003263 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
3264 std::string reason = std::string("reason=pointer cancel on split window");
3265 android_log_event_list(LOGTAG_INPUT_CANCEL)
3266 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3267 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003268 if (DEBUG_FOCUS) {
3269 ALOGD("channel '%s' ~ Split motion event.",
3270 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003271 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003272 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003273 enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection,
3274 std::move(splitMotionEntry),
3275 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003276 return;
3277 }
3278 }
3279
3280 // Not splitting. Enqueue dispatch entries for the event as is.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003281 enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection, eventEntry,
3282 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003283}
3284
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003285void InputDispatcher::enqueueDispatchEntryAndStartDispatchCycleLocked(
3286 nsecs_t currentTime, const std::shared_ptr<Connection>& connection,
3287 std::shared_ptr<const EventEntry> eventEntry, const InputTarget& inputTarget) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003288 ATRACE_NAME_IF(ATRACE_ENABLED(),
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003289 StringPrintf("enqueueDispatchEntryAndStartDispatchCycleLocked(inputChannel=%s, "
3290 "id=0x%" PRIx32 ")",
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003291 connection->getInputChannelName().c_str(), eventEntry->id));
Michael Wright3dd60e22019-03-27 22:06:44 +00003292
hongzuo liu95785e22022-09-06 02:51:35 +00003293 const bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003294
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003295 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003296
3297 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003298 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003299 startDispatchCycleLocked(currentTime, connection);
3300 }
3301}
3302
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003303void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,
Prabir Pradhan24047542023-11-02 17:14:59 +00003304 std::shared_ptr<const EventEntry> eventEntry,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003305 const InputTarget& inputTarget) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003306 // This is a new event.
3307 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003308 std::unique_ptr<DispatchEntry> dispatchEntry =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003309 createDispatchEntry(inputTarget, eventEntry, inputTarget.flags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003310
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003311 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
3312 // different EventEntry than what was passed in.
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003313 eventEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003314 // Apply target flags and update the connection's input state.
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003315 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003316 case EventEntry::Type::KEY: {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003317 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*eventEntry);
3318 if (!connection->inputState.trackKey(keyEntry, keyEntry.flags)) {
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -07003319 LOG(WARNING) << "channel " << connection->getInputChannelName()
3320 << "~ dropping inconsistent event: " << *dispatchEntry;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003321 return; // skip the inconsistent event
3322 }
3323 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003324 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003325
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003326 case EventEntry::Type::MOTION: {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003327 std::shared_ptr<const MotionEntry> resolvedMotion =
3328 std::static_pointer_cast<const MotionEntry>(eventEntry);
3329 {
3330 // Determine the resolved motion entry.
3331 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
3332 int32_t resolvedAction = motionEntry.action;
3333 int32_t resolvedFlags = motionEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003334
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003335 if (inputTarget.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003336 resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003337 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003338 resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003339 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_ENTER) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003340 resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003341 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_EXIT) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003342 resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003343 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_ENTER) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003344 resolvedAction = AMOTION_EVENT_ACTION_DOWN;
3345 }
3346 if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
3347 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3348 motionEntry.displayId)) {
3349 if (DEBUG_DISPATCH_CYCLE) {
3350 LOG(DEBUG) << "channel '" << connection->getInputChannelName().c_str()
3351 << "' ~ enqueueDispatchEntryLocked: filling in missing hover "
3352 "enter event";
3353 }
3354 resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3355 }
3356
3357 if (resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
3358 resolvedFlags |= AMOTION_EVENT_FLAG_CANCELED;
3359 }
3360 if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) {
3361 resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3362 }
3363 if (dispatchEntry->targetFlags.test(
3364 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED)) {
3365 resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3366 }
3367
3368 dispatchEntry->resolvedFlags = resolvedFlags;
3369 if (resolvedAction != motionEntry.action) {
3370 // Generate a new MotionEntry with a new eventId using the resolved action and
3371 // flags.
3372 resolvedMotion =
3373 std::make_shared<MotionEntry>(mIdGenerator.nextId(),
3374 motionEntry.injectionState,
3375 motionEntry.eventTime,
3376 motionEntry.deviceId, motionEntry.source,
3377 motionEntry.displayId,
3378 motionEntry.policyFlags, resolvedAction,
3379 motionEntry.actionButton, resolvedFlags,
3380 motionEntry.metaState,
3381 motionEntry.buttonState,
3382 motionEntry.classification,
3383 motionEntry.edgeFlags,
3384 motionEntry.xPrecision,
3385 motionEntry.yPrecision,
3386 motionEntry.xCursorPosition,
3387 motionEntry.yCursorPosition,
3388 motionEntry.downTime,
3389 motionEntry.pointerProperties,
3390 motionEntry.pointerCoords);
3391 if (ATRACE_ENABLED()) {
3392 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3393 ") to MotionEvent(id=0x%" PRIx32 ").",
3394 motionEntry.id, resolvedMotion->id);
3395 ATRACE_NAME(message.c_str());
3396 }
3397
3398 // Set the resolved motion entry in the DispatchEntry.
3399 dispatchEntry->eventEntry = resolvedMotion;
3400 eventEntry = resolvedMotion;
3401 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003402 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003403
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003404 // Check if we need to cancel any of the ongoing gestures. We don't support multiple
3405 // devices being active at the same time in the same window, so if a new device is
3406 // active, cancel the gesture from the old device.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003407 std::unique_ptr<EventEntry> cancelEvent =
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003408 connection->inputState.cancelConflictingInputStream(*resolvedMotion);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003409 if (cancelEvent != nullptr) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003410 LOG(INFO) << "Canceling pointers for device " << resolvedMotion->deviceId << " in "
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003411 << connection->getInputChannelName() << " with event "
3412 << cancelEvent->getDescription();
3413 std::unique_ptr<DispatchEntry> cancelDispatchEntry =
3414 createDispatchEntry(inputTarget, std::move(cancelEvent),
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003415 ftl::Flags<InputTarget::Flags>());
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003416
3417 // Send these cancel events to the queue before sending the event from the new
3418 // device.
3419 connection->outboundQueue.emplace_back(std::move(cancelDispatchEntry));
3420 }
3421
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003422 if (!connection->inputState.trackMotion(*resolvedMotion,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003423 dispatchEntry->resolvedFlags)) {
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -07003424 LOG(WARNING) << "channel " << connection->getInputChannelName()
3425 << "~ dropping inconsistent event: " << *dispatchEntry;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003426 return; // skip the inconsistent event
3427 }
3428
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003429 if ((resolvedMotion->flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3430 (resolvedMotion->policyFlags & POLICY_FLAG_TRUSTED)) {
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003431 // Skip reporting pointer down outside focus to the policy.
3432 break;
3433 }
3434
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003435 dispatchPointerDownOutsideFocus(resolvedMotion->source, resolvedMotion->action,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003436 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003437
3438 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003439 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003440 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003441 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003442 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3443 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003444 break;
3445 }
Chris Yef59a2f42020-10-16 12:55:26 -07003446 case EventEntry::Type::SENSOR: {
3447 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3448 break;
3449 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003450 case EventEntry::Type::CONFIGURATION_CHANGED:
3451 case EventEntry::Type::DEVICE_RESET: {
3452 LOG_ALWAYS_FATAL("%s events should not go to apps",
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003453 ftl::enum_string(eventEntry->type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003454 break;
3455 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003456 }
3457
3458 // Remember that we are waiting for this dispatch to complete.
3459 if (dispatchEntry->hasForegroundTarget()) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003460 incrementPendingForegroundDispatches(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003461 }
3462
3463 // Enqueue the dispatch entry.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003464 connection->outboundQueue.emplace_back(std::move(dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003465 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003466}
3467
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003468/**
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003469 * This function is for debugging and metrics collection. It has two roles.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003470 *
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003471 * The first role is to log input interaction with windows, which helps determine what the user was
3472 * interacting with. For example, if user is touching launcher, we will see an input_interaction log
3473 * that user started interacting with launcher window, as well as any other window that received
3474 * that gesture, such as the wallpaper or other spy windows. A new input_interaction is only logged
3475 * when the set of tokens that received the event changes. It is not logged again as long as the
3476 * user is interacting with the same windows.
3477 *
3478 * The second role is to track input device activity for metrics collection. For each input event,
3479 * we report the set of UIDs that the input device interacted with to the policy. Unlike for the
3480 * input_interaction logs, the device interaction is reported even when the set of interaction
3481 * tokens do not change.
3482 *
3483 * For these purposes, we do not count ACTION_OUTSIDE, ACTION_UP and ACTION_CANCEL actions as
3484 * interaction. This includes up and cancel events for both keys and motions.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003485 */
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003486void InputDispatcher::processInteractionsLocked(const EventEntry& entry,
3487 const std::vector<InputTarget>& targets) {
3488 int32_t deviceId;
3489 nsecs_t eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003490 // Skip ACTION_UP events, and all events other than keys and motions
3491 if (entry.type == EventEntry::Type::KEY) {
3492 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3493 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3494 return;
3495 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003496 deviceId = keyEntry.deviceId;
3497 eventTime = keyEntry.eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003498 } else if (entry.type == EventEntry::Type::MOTION) {
3499 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3500 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003501 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
3502 MotionEvent::getActionMasked(motionEntry.action) == AMOTION_EVENT_ACTION_POINTER_UP) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003503 return;
3504 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003505 deviceId = motionEntry.deviceId;
3506 eventTime = motionEntry.eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003507 } else {
3508 return; // Not a key or a motion
3509 }
3510
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003511 std::set<gui::Uid> interactionUids;
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003512 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003513 std::vector<std::shared_ptr<Connection>> newConnections;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003514 for (const InputTarget& target : targets) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003515 if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003516 continue; // Skip windows that receive ACTION_OUTSIDE
3517 }
3518
3519 sp<IBinder> token = target.inputChannel->getConnectionToken();
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003520 std::shared_ptr<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003521 if (connection == nullptr) {
3522 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003523 }
3524 newConnectionTokens.insert(std::move(token));
3525 newConnections.emplace_back(connection);
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003526 if (target.windowHandle) {
3527 interactionUids.emplace(target.windowHandle->getInfo()->ownerUid);
3528 }
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003529 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003530
3531 auto command = [this, deviceId, eventTime, uids = std::move(interactionUids)]()
3532 REQUIRES(mLock) {
3533 scoped_unlock unlock(mLock);
3534 mPolicy.notifyDeviceInteraction(deviceId, eventTime, uids);
3535 };
3536 postCommandLocked(std::move(command));
3537
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003538 if (newConnectionTokens == mInteractionConnectionTokens) {
3539 return; // no change
3540 }
3541 mInteractionConnectionTokens = newConnectionTokens;
3542
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003543 std::string targetList;
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003544 for (const std::shared_ptr<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003545 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003546 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003547 std::string message = "Interaction with: " + targetList;
3548 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003549 message += "<none>";
3550 }
3551 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3552}
3553
chaviwfd6d3512019-03-25 13:23:49 -07003554void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003555 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003556 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003557 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3558 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003559 return;
3560 }
3561
Vishnu Nairc519ff72021-01-21 08:23:08 -08003562 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003563 if (focusedToken == token) {
3564 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003565 return;
3566 }
3567
Prabir Pradhancef936d2021-07-21 16:17:52 +00003568 auto command = [this, token]() REQUIRES(mLock) {
3569 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003570 mPolicy.onPointerDownOutsideFocus(token);
Prabir Pradhancef936d2021-07-21 16:17:52 +00003571 };
3572 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003573}
3574
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003575status_t InputDispatcher::publishMotionEvent(Connection& connection,
3576 DispatchEntry& dispatchEntry) const {
3577 const EventEntry& eventEntry = *(dispatchEntry.eventEntry);
3578 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3579
3580 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003581 const PointerCoords* usingCoords = motionEntry.pointerCoords.data();
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003582
3583 // Set the X and Y offset and X and Y scale depending on the input source.
3584 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003585 !(dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS))) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003586 float globalScaleFactor = dispatchEntry.globalScaleFactor;
3587 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003588 for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003589 scaledCoords[i] = motionEntry.pointerCoords[i];
3590 // Don't apply window scale here since we don't want scale to affect raw
3591 // coordinates. The scale will be sent back to the client and applied
3592 // later when requesting relative coordinates.
Harry Cutts33476232023-01-30 19:57:29 +00003593 scaledCoords[i].scale(globalScaleFactor, /*windowXScale=*/1, /*windowYScale=*/1);
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003594 }
3595 usingCoords = scaledCoords;
3596 }
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003597 } else if (dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS)) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003598 // We don't want the dispatch target to know the coordinates
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003599 for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003600 scaledCoords[i].clear();
3601 }
3602 usingCoords = scaledCoords;
3603 }
3604
3605 std::array<uint8_t, 32> hmac = getSignature(motionEntry, dispatchEntry);
3606
3607 // Publish the motion event.
3608 return connection.inputPublisher
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003609 .publishMotionEvent(dispatchEntry.seq, motionEntry.id, motionEntry.deviceId,
3610 motionEntry.source, motionEntry.displayId, std::move(hmac),
3611 motionEntry.action, motionEntry.actionButton,
3612 dispatchEntry.resolvedFlags, motionEntry.edgeFlags,
3613 motionEntry.metaState, motionEntry.buttonState,
3614 motionEntry.classification, dispatchEntry.transform,
3615 motionEntry.xPrecision, motionEntry.yPrecision,
3616 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
3617 dispatchEntry.rawTransform, motionEntry.downTime,
3618 motionEntry.eventTime, motionEntry.getPointerCount(),
3619 motionEntry.pointerProperties.data(), usingCoords);
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003620}
3621
Michael Wrightd02c5b62014-02-10 15:10:22 -08003622void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003623 const std::shared_ptr<Connection>& connection) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003624 ATRACE_NAME_IF(ATRACE_ENABLED(),
3625 StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
3626 connection->getInputChannelName().c_str()));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003627 if (DEBUG_DISPATCH_CYCLE) {
3628 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3629 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003630
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003631 while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003632 std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003633 dispatchEntry->deliveryTime = currentTime;
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08003634 const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003635 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003636
3637 // Publish the event.
3638 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003639 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3640 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003641 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003642 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3643 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003644 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003645 LOG(INFO) << "Publishing " << *dispatchEntry << " to "
3646 << connection->getInputChannelName();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003647 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003648
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003649 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003650 status = connection->inputPublisher
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003651 .publishKeyEvent(dispatchEntry->seq, keyEntry.id,
3652 keyEntry.deviceId, keyEntry.source,
3653 keyEntry.displayId, std::move(hmac),
3654 keyEntry.action, dispatchEntry->resolvedFlags,
3655 keyEntry.keyCode, keyEntry.scanCode,
3656 keyEntry.metaState, keyEntry.repeatCount,
3657 keyEntry.downTime, keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003658 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003659 }
3660
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003661 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003662 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003663 LOG(INFO) << "Publishing " << *dispatchEntry << " to "
3664 << connection->getInputChannelName();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003665 }
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003666 status = publishMotionEvent(*connection, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003667 break;
3668 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003669
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003670 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003671 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003672 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003673 focusEntry.id,
Antonio Kantek3cfec7b2021-11-05 18:26:17 -07003674 focusEntry.hasFocus);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003675 break;
3676 }
3677
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003678 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3679 const TouchModeEntry& touchModeEntry =
3680 static_cast<const TouchModeEntry&>(eventEntry);
3681 status = connection->inputPublisher
3682 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3683 touchModeEntry.inTouchMode);
3684
3685 break;
3686 }
3687
Prabir Pradhan99987712020-11-10 18:43:05 -08003688 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3689 const auto& captureEntry =
3690 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3691 status = connection->inputPublisher
3692 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003693 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003694 break;
3695 }
3696
arthurhungb89ccb02020-12-30 16:19:01 +08003697 case EventEntry::Type::DRAG: {
3698 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3699 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3700 dragEntry.id, dragEntry.x,
3701 dragEntry.y,
3702 dragEntry.isExiting);
3703 break;
3704 }
3705
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003706 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003707 case EventEntry::Type::DEVICE_RESET:
3708 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003709 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003710 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003711 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003712 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003713 }
3714
3715 // Check the result.
3716 if (status) {
3717 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003718 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003719 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003720 "This is unexpected because the wait queue is empty, so the pipe "
3721 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003722 "event to it, status=%s(%d)",
3723 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3724 status);
Harry Cutts33476232023-01-30 19:57:29 +00003725 abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003726 } else {
3727 // Pipe is full and we are waiting for the app to finish process some events
3728 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003729 if (DEBUG_DISPATCH_CYCLE) {
3730 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3731 "waiting for the application to catch up",
3732 connection->getInputChannelName().c_str());
3733 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003734 }
3735 } else {
3736 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003737 "status=%s(%d)",
3738 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3739 status);
Harry Cutts33476232023-01-30 19:57:29 +00003740 abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003741 }
3742 return;
3743 }
3744
3745 // Re-enqueue the event on the wait queue.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003746 const nsecs_t timeoutTime = dispatchEntry->timeoutTime;
3747 connection->waitQueue.emplace_back(std::move(dispatchEntry));
3748 connection->outboundQueue.erase(connection->outboundQueue.begin());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003749 traceOutboundQueueLength(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003750 if (connection->responsive) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003751 mAnrTracker.insert(timeoutTime, connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003752 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003753 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003754 }
3755}
3756
chaviw09c8d2d2020-08-24 15:48:26 -07003757std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3758 size_t size;
3759 switch (event.type) {
3760 case VerifiedInputEvent::Type::KEY: {
3761 size = sizeof(VerifiedKeyEvent);
3762 break;
3763 }
3764 case VerifiedInputEvent::Type::MOTION: {
3765 size = sizeof(VerifiedMotionEvent);
3766 break;
3767 }
3768 }
3769 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3770 return mHmacKeyManager.sign(start, size);
3771}
3772
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003773const std::array<uint8_t, 32> InputDispatcher::getSignature(
3774 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003775 const int32_t actionMasked = MotionEvent::getActionMasked(motionEntry.action);
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003776 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003777 // Only sign events up and down events as the purely move events
3778 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003779 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003780 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003781
3782 VerifiedMotionEvent verifiedEvent =
3783 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3784 verifiedEvent.actionMasked = actionMasked;
3785 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3786 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003787}
3788
3789const std::array<uint8_t, 32> InputDispatcher::getSignature(
3790 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3791 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3792 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003793 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003794}
3795
Michael Wrightd02c5b62014-02-10 15:10:22 -08003796void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003797 const std::shared_ptr<Connection>& connection,
3798 uint32_t seq, bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003799 if (DEBUG_DISPATCH_CYCLE) {
3800 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3801 connection->getInputChannelName().c_str(), seq, toString(handled));
3802 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003803
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003804 if (connection->status == Connection::Status::BROKEN ||
3805 connection->status == Connection::Status::ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003806 return;
3807 }
3808
3809 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003810 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3811 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3812 };
3813 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003814}
3815
3816void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003817 const std::shared_ptr<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003818 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003819 if (DEBUG_DISPATCH_CYCLE) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003820 LOG(INFO) << "channel '" << connection->getInputChannelName() << "'~ " << __func__
3821 << " - notify=" << toString(notify);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003822 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003823
3824 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003825 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003826 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003827 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003828 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003829
3830 // The connection appears to be unrecoverably broken.
3831 // Ignore already broken or zombie connections.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003832 if (connection->status == Connection::Status::NORMAL) {
3833 connection->status = Connection::Status::BROKEN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003834
3835 if (notify) {
3836 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003837 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3838 connection->getInputChannelName().c_str());
3839
3840 auto command = [this, connection]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003841 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003842 mPolicy.notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Prabir Pradhancef936d2021-07-21 16:17:52 +00003843 };
3844 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003845 }
3846 }
3847}
3848
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003849void InputDispatcher::drainDispatchQueue(std::deque<std::unique_ptr<DispatchEntry>>& queue) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003850 while (!queue.empty()) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003851 releaseDispatchEntry(std::move(queue.front()));
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003852 queue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003853 }
3854}
3855
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003856void InputDispatcher::releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003857 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003858 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003859 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003860}
3861
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003862int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3863 std::scoped_lock _l(mLock);
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003864 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003865 if (connection == nullptr) {
3866 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3867 connectionToken.get(), events);
3868 return 0; // remove the callback
3869 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003870
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003871 bool notify;
3872 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3873 if (!(events & ALOOPER_EVENT_INPUT)) {
3874 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3875 "events=0x%x",
3876 connection->getInputChannelName().c_str(), events);
3877 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003878 }
3879
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003880 nsecs_t currentTime = now();
3881 bool gotOne = false;
3882 status_t status = OK;
3883 for (;;) {
3884 Result<InputPublisher::ConsumerResponse> result =
3885 connection->inputPublisher.receiveConsumerResponse();
3886 if (!result.ok()) {
3887 status = result.error().code();
3888 break;
3889 }
3890
3891 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3892 const InputPublisher::Finished& finish =
3893 std::get<InputPublisher::Finished>(*result);
3894 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3895 finish.consumeTime);
3896 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003897 if (shouldReportMetricsForConnection(*connection)) {
3898 const InputPublisher::Timeline& timeline =
3899 std::get<InputPublisher::Timeline>(*result);
3900 mLatencyTracker
3901 .trackGraphicsLatency(timeline.inputEventId,
3902 connection->inputChannel->getConnectionToken(),
3903 std::move(timeline.graphicsTimeline));
3904 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003905 }
3906 gotOne = true;
3907 }
3908 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003909 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003910 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003911 return 1;
3912 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003913 }
3914
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003915 notify = status != DEAD_OBJECT || !connection->monitor;
3916 if (notify) {
3917 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3918 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3919 status);
3920 }
3921 } else {
3922 // Monitor channels are never explicitly unregistered.
3923 // We do it automatically when the remote endpoint is closed so don't warn about them.
3924 const bool stillHaveWindowHandle =
3925 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3926 notify = !connection->monitor && stillHaveWindowHandle;
3927 if (notify) {
3928 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3929 connection->getInputChannelName().c_str(), events);
3930 }
3931 }
3932
3933 // Remove the channel.
3934 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3935 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003936}
3937
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003938void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003939 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003940 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003941 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003942 }
3943}
3944
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003945void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003946 const CancelationOptions& options) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08003947 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003948 for (const Monitor& monitor : monitors) {
3949 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003950 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003951 }
3952}
3953
Michael Wrightd02c5b62014-02-10 15:10:22 -08003954void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003955 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003956 std::shared_ptr<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003957 if (connection == nullptr) {
3958 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003959 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003960
3961 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962}
3963
3964void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003965 const std::shared_ptr<Connection>& connection, const CancelationOptions& options) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003966 if (connection->status == Connection::Status::BROKEN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003967 return;
3968 }
3969
3970 nsecs_t currentTime = now();
3971
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003972 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003973 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003974
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003975 if (cancelationEvents.empty()) {
3976 return;
3977 }
Vaibhav Devmurari110ba322023-11-17 10:47:16 +00003978
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003979 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3980 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Siarhei Vishniakou2e3e4432023-02-09 18:34:11 -08003981 "with reality: %s, mode=%s.",
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003982 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
Siarhei Vishniakou2e3e4432023-02-09 18:34:11 -08003983 ftl::enum_string(options.mode).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003984 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003985
Arthur Hungb3307ee2021-10-14 10:57:37 +00003986 std::string reason = std::string("reason=").append(options.reason);
3987 android_log_event_list(LOGTAG_INPUT_CANCEL)
3988 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3989
hongzuo liu95785e22022-09-06 02:51:35 +00003990 const bool wasEmpty = connection->outboundQueue.empty();
Prabir Pradhan16463382023-10-12 23:03:19 +00003991 // The target to use if we don't find a window associated with the channel.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003992 const InputTarget fallbackTarget{.inputChannel = connection->inputChannel};
Prabir Pradhan16463382023-10-12 23:03:19 +00003993 const auto& token = connection->inputChannel->getConnectionToken();
hongzuo liu95785e22022-09-06 02:51:35 +00003994
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003995 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003996 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00003997 std::vector<InputTarget> targets{};
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00003998
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003999 switch (cancelationEventEntry->type) {
4000 case EventEntry::Type::KEY: {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004001 const auto& keyEntry = static_cast<const KeyEntry&>(*cancelationEventEntry);
Prabir Pradhan16463382023-10-12 23:03:19 +00004002 const std::optional<int32_t> targetDisplay = keyEntry.displayId != ADISPLAY_ID_NONE
4003 ? std::make_optional(keyEntry.displayId)
4004 : std::nullopt;
4005 if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004006 addWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
4007 /*targetFlags=*/{}, keyEntry.downTime, targets);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004008 } else {
4009 targets.emplace_back(fallbackTarget);
4010 }
4011 logOutboundKeyDetails("cancel - ", keyEntry);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004012 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004013 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004014 case EventEntry::Type::MOTION: {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004015 const auto& motionEntry = static_cast<const MotionEntry&>(*cancelationEventEntry);
Prabir Pradhan16463382023-10-12 23:03:19 +00004016 const std::optional<int32_t> targetDisplay =
4017 motionEntry.displayId != ADISPLAY_ID_NONE
4018 ? std::make_optional(motionEntry.displayId)
4019 : std::nullopt;
4020 if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004021 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004022 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004023 pointerIndex++) {
4024 pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4025 }
Vaibhav Devmurari110ba322023-11-17 10:47:16 +00004026 if (mDragState && mDragState->dragWindow->getToken() == token &&
4027 pointerIds.test(mDragState->pointerId)) {
4028 LOG(INFO) << __func__
4029 << ": Canceling drag and drop because the pointers for the drag "
4030 "window are being canceled.";
4031 sendDropWindowCommandLocked(nullptr, /*x=*/0, /*y=*/0);
4032 mDragState.reset();
4033 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004034 addPointerWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
4035 ftl::Flags<InputTarget::Flags>(), pointerIds,
4036 motionEntry.downTime, targets);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004037 } else {
4038 targets.emplace_back(fallbackTarget);
4039 const auto it = mDisplayInfos.find(motionEntry.displayId);
4040 if (it != mDisplayInfos.end()) {
4041 targets.back().displayTransform = it->second.transform;
4042 targets.back().setDefaultPointerTransform(it->second.transform);
4043 }
4044 }
4045 logOutboundMotionDetails("cancel - ", motionEntry);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004046 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004047 }
Prabir Pradhan99987712020-11-10 18:43:05 -08004048 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004049 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08004050 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
4051 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08004052 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08004053 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004054 break;
4055 }
4056 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07004057 case EventEntry::Type::DEVICE_RESET:
4058 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004059 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08004060 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004061 break;
4062 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004063 }
4064
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004065 if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004066 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), targets[0]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004067 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004068
hongzuo liu95785e22022-09-06 02:51:35 +00004069 // If the outbound queue was previously empty, start the dispatch cycle going.
4070 if (wasEmpty && !connection->outboundQueue.empty()) {
4071 startDispatchCycleLocked(currentTime, connection);
4072 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004073}
4074
Svet Ganov5d3bc372020-01-26 23:11:07 -08004075void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07004076 const nsecs_t downTime, const std::shared_ptr<Connection>& connection,
Arthur Hungc539dbb2022-12-08 07:45:36 +00004077 ftl::Flags<InputTarget::Flags> targetFlags) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08004078 if (connection->status == Connection::Status::BROKEN) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004079 return;
4080 }
4081
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004082 std::vector<std::unique_ptr<EventEntry>> downEvents =
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004083 connection->inputState.synthesizePointerDownEvents(downTime);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004084
4085 if (downEvents.empty()) {
4086 return;
4087 }
4088
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004089 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004090 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
4091 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004092 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08004093
chaviw98318de2021-05-19 16:45:23 -05004094 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08004095 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Svet Ganov5d3bc372020-01-26 23:11:07 -08004096
hongzuo liu95785e22022-09-06 02:51:35 +00004097 const bool wasEmpty = connection->outboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004098 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004099 std::vector<InputTarget> targets{};
Svet Ganov5d3bc372020-01-26 23:11:07 -08004100 switch (downEventEntry->type) {
4101 case EventEntry::Type::MOTION: {
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004102 const auto& motionEntry = static_cast<const MotionEntry&>(*downEventEntry);
4103 if (windowHandle != nullptr) {
4104 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004105 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004106 pointerIndex++) {
4107 pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4108 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004109 addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::AS_IS,
4110 targetFlags, pointerIds, motionEntry.downTime,
4111 targets);
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004112 } else {
4113 targets.emplace_back(InputTarget{.inputChannel = connection->inputChannel,
4114 .flags = targetFlags});
4115 const auto it = mDisplayInfos.find(motionEntry.displayId);
4116 if (it != mDisplayInfos.end()) {
4117 targets.back().displayTransform = it->second.transform;
4118 targets.back().setDefaultPointerTransform(it->second.transform);
4119 }
4120 }
4121 logOutboundMotionDetails("down - ", motionEntry);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004122 break;
4123 }
4124
4125 case EventEntry::Type::KEY:
4126 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004127 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08004128 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08004129 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07004130 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08004131 case EventEntry::Type::SENSOR:
4132 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004133 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08004134 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08004135 break;
4136 }
4137 }
4138
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004139 if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004140 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), targets[0]);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004141 }
4142
hongzuo liu95785e22022-09-06 02:51:35 +00004143 // If the outbound queue was previously empty, start the dispatch cycle going.
4144 if (wasEmpty && !connection->outboundQueue.empty()) {
4145 startDispatchCycleLocked(downTime, connection);
4146 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08004147}
4148
Arthur Hungc539dbb2022-12-08 07:45:36 +00004149void InputDispatcher::synthesizeCancelationEventsForWindowLocked(
4150 const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options) {
4151 if (windowHandle != nullptr) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07004152 std::shared_ptr<Connection> wallpaperConnection =
4153 getConnectionLocked(windowHandle->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00004154 if (wallpaperConnection != nullptr) {
4155 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection, options);
4156 }
4157 }
4158}
4159
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004160std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004161 const MotionEntry& originalMotionEntry, std::bitset<MAX_POINTER_ID + 1> pointerIds,
4162 nsecs_t splitDownTime) {
4163 ALOG_ASSERT(pointerIds.any());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004164
4165 uint32_t splitPointerIndexMap[MAX_POINTERS];
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004166 std::vector<PointerProperties> splitPointerProperties;
4167 std::vector<PointerCoords> splitPointerCoords;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004168
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004169 uint32_t originalPointerCount = originalMotionEntry.getPointerCount();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004170 uint32_t splitPointerCount = 0;
4171
4172 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004173 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004174 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004175 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004176 uint32_t pointerId = uint32_t(pointerProperties.id);
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004177 if (pointerIds.test(pointerId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004178 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004179 splitPointerProperties.push_back(pointerProperties);
4180 splitPointerCoords.push_back(originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004181 splitPointerCount += 1;
4182 }
4183 }
4184
4185 if (splitPointerCount != pointerIds.count()) {
4186 // This is bad. We are missing some of the pointers that we expected to deliver.
4187 // Most likely this indicates that we received an ACTION_MOVE events that has
4188 // different pointer ids than we expected based on the previous ACTION_DOWN
4189 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
4190 // in this way.
4191 ALOGW("Dropping split motion event because the pointer count is %d but "
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004192 "we expected there to be %zu pointers. This probably means we received "
Siarhei Vishniakou16e4fa02023-02-16 17:48:56 -08004193 "a broken sequence of pointer ids from the input device: %s",
4194 splitPointerCount, pointerIds.count(), originalMotionEntry.getDescription().c_str());
Yi Kong9b14ac62018-07-17 13:48:38 -07004195 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004196 }
4197
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004198 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004199 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004200 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
4201 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07004202 int32_t originalPointerIndex = MotionEvent::getActionIndex(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004203 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004204 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004205 uint32_t pointerId = uint32_t(pointerProperties.id);
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004206 if (pointerIds.test(pointerId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004207 if (pointerIds.count() == 1) {
4208 // The first/last pointer went down/up.
4209 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004210 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08004211 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
4212 ? AMOTION_EVENT_ACTION_CANCEL
4213 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004214 } else {
4215 // A secondary pointer went down/up.
4216 uint32_t splitPointerIndex = 0;
4217 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
4218 splitPointerIndex += 1;
4219 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004220 action = maskedAction |
4221 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004222 }
4223 } else {
4224 // An unrelated pointer changed.
4225 action = AMOTION_EVENT_ACTION_MOVE;
4226 }
4227 }
4228
Siarhei Vishniakou59e302b2023-06-05 08:04:53 -07004229 if (action == AMOTION_EVENT_ACTION_DOWN && splitDownTime != originalMotionEntry.eventTime) {
4230 logDispatchStateLocked();
4231 LOG_ALWAYS_FATAL("Split motion event has mismatching downTime and eventTime for "
4232 "ACTION_DOWN, motionEntry=%s, splitDownTime=%" PRId64,
4233 originalMotionEntry.getDescription().c_str(), splitDownTime);
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004234 }
4235
Garfield Tanff1f1bb2020-01-28 13:24:04 -08004236 int32_t newId = mIdGenerator.nextId();
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00004237 ATRACE_NAME_IF(ATRACE_ENABLED(),
4238 StringPrintf("Split MotionEvent(id=0x%" PRIx32 ") to MotionEvent(id=0x%" PRIx32
4239 ").",
4240 originalMotionEntry.id, newId));
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004241 std::unique_ptr<MotionEntry> splitMotionEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004242 std::make_unique<MotionEntry>(newId, originalMotionEntry.injectionState,
4243 originalMotionEntry.eventTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004244 originalMotionEntry.deviceId, originalMotionEntry.source,
4245 originalMotionEntry.displayId,
4246 originalMotionEntry.policyFlags, action,
4247 originalMotionEntry.actionButton,
4248 originalMotionEntry.flags, originalMotionEntry.metaState,
4249 originalMotionEntry.buttonState,
4250 originalMotionEntry.classification,
4251 originalMotionEntry.edgeFlags,
4252 originalMotionEntry.xPrecision,
4253 originalMotionEntry.yPrecision,
4254 originalMotionEntry.xCursorPosition,
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004255 originalMotionEntry.yCursorPosition, splitDownTime,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004256 splitPointerProperties, splitPointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004257
Michael Wrightd02c5b62014-02-10 15:10:22 -08004258 return splitMotionEntry;
4259}
4260
Asmita Poddardd9a6cd2023-09-26 15:35:12 +00004261void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
4262 std::scoped_lock _l(mLock);
4263 mLatencyTracker.setInputDevices(args.inputDeviceInfos);
4264}
4265
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004266void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004267 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004268 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args.eventTime);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004269 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004270
Antonio Kantekf16f2832021-09-28 04:39:20 +00004271 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004272 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004273 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004274
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004275 std::unique_ptr<ConfigurationChangedEntry> newEntry =
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004276 std::make_unique<ConfigurationChangedEntry>(args.id, args.eventTime);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004277 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004278 } // release lock
4279
4280 if (needWake) {
4281 mLooper->wake();
4282 }
4283}
4284
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004285void InputDispatcher::notifyKey(const NotifyKeyArgs& args) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004286 ALOGD_IF(debugInboundEventDetails(),
4287 "notifyKey - id=%" PRIx32 ", eventTime=%" PRId64
4288 ", deviceId=%d, source=%s, displayId=%" PRId32
4289 "policyFlags=0x%x, action=%s, flags=0x%x, keyCode=%s, scanCode=0x%x, metaState=0x%x, "
4290 "downTime=%" PRId64,
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004291 args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4292 args.displayId, args.policyFlags, KeyEvent::actionToString(args.action), args.flags,
4293 KeyEvent::getLabel(args.keyCode), args.scanCode, args.metaState, args.downTime);
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004294 Result<void> keyCheck = validateKeyEvent(args.action);
4295 if (!keyCheck.ok()) {
4296 LOG(ERROR) << "invalid key event: " << keyCheck.error();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004297 return;
4298 }
4299
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004300 uint32_t policyFlags = args.policyFlags;
4301 int32_t flags = args.flags;
4302 int32_t metaState = args.metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07004303 // InputDispatcher tracks and generates key repeats on behalf of
4304 // whatever notifies it, so repeatCount should always be set to 0
4305 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004306 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
4307 policyFlags |= POLICY_FLAG_VIRTUAL;
4308 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
4309 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004310 if (policyFlags & POLICY_FLAG_FUNCTION) {
4311 metaState |= AMETA_FUNCTION_ON;
4312 }
4313
4314 policyFlags |= POLICY_FLAG_TRUSTED;
4315
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004316 int32_t keyCode = args.keyCode;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004317 KeyEvent event;
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004318 event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC, args.action,
4319 flags, keyCode, args.scanCode, metaState, repeatCount, args.downTime,
4320 args.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004321
Michael Wright2b3c3302018-03-02 17:19:13 +00004322 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004323 mPolicy.interceptKeyBeforeQueueing(event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004324 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4325 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004326 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004327 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004328
Antonio Kantekf16f2832021-09-28 04:39:20 +00004329 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004330 { // acquire lock
4331 mLock.lock();
4332
4333 if (shouldSendKeyToInputFilterLocked(args)) {
4334 mLock.unlock();
4335
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004336 policyFlags |= POLICY_FLAG_FILTERED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004337 if (!mPolicy.filterInputEvent(event, policyFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004338 return; // event was consumed by the filter
4339 }
4340
4341 mLock.lock();
4342 }
4343
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004344 std::unique_ptr<KeyEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004345 std::make_unique<KeyEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4346 args.deviceId, args.source, args.displayId, policyFlags,
4347 args.action, flags, keyCode, args.scanCode, metaState,
4348 repeatCount, args.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004349
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004350 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004351 mLock.unlock();
4352 } // release lock
4353
4354 if (needWake) {
4355 mLooper->wake();
4356 }
4357}
4358
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004359bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs& args) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004360 return mInputFilterEnabled;
4361}
4362
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004363void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004364 if (debugInboundEventDetails()) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004365 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=%s, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004366 "displayId=%" PRId32 ", policyFlags=0x%x, "
Siarhei Vishniakou6ebd0692022-10-20 15:05:45 -07004367 "action=%s, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004368 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
4369 "yCursorPosition=%f, downTime=%" PRId64,
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004370 args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4371 args.displayId, args.policyFlags, MotionEvent::actionToString(args.action).c_str(),
4372 args.actionButton, args.flags, args.metaState, args.buttonState, args.edgeFlags,
4373 args.xPrecision, args.yPrecision, args.xCursorPosition, args.yCursorPosition,
4374 args.downTime);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004375 for (uint32_t i = 0; i < args.getPointerCount(); i++) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004376 ALOGD(" Pointer %d: id=%d, toolType=%s, x=%f, y=%f, pressure=%f, size=%f, "
4377 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, orientation=%f",
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004378 i, args.pointerProperties[i].id,
4379 ftl::enum_string(args.pointerProperties[i].toolType).c_str(),
4380 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
4381 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
4382 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
4383 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
4384 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
4385 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
4386 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
4387 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
4388 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004389 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004390 }
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004391
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004392 Result<void> motionCheck =
4393 validateMotionEvent(args.action, args.actionButton, args.getPointerCount(),
4394 args.pointerProperties.data());
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004395 if (!motionCheck.ok()) {
4396 LOG(FATAL) << "Invalid event: " << args.dump() << "; reason: " << motionCheck.error();
4397 return;
4398 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004399
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07004400 if (DEBUG_VERIFY_EVENTS) {
4401 auto [it, _] =
4402 mVerifiersByDisplay.try_emplace(args.displayId,
4403 StringPrintf("display %" PRId32, args.displayId));
4404 Result<void> result =
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -07004405 it->second.processMovement(args.deviceId, args.source, args.action,
4406 args.getPointerCount(), args.pointerProperties.data(),
4407 args.pointerCoords.data(), args.flags);
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07004408 if (!result.ok()) {
4409 LOG(FATAL) << "Bad stream: " << result.error() << " caused by " << args.dump();
4410 }
4411 }
4412
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004413 uint32_t policyFlags = args.policyFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004414 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004415
4416 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004417 mPolicy.interceptMotionBeforeQueueing(args.displayId, args.eventTime, policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004418 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4419 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004420 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004421 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004422
Antonio Kantekf16f2832021-09-28 04:39:20 +00004423 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004424 { // acquire lock
4425 mLock.lock();
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004426 if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
4427 // Set the flag anyway if we already have an ongoing gesture. That would allow us to
4428 // complete the processing of the current stroke.
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004429 const auto touchStateIt = mTouchStatesByDisplay.find(args.displayId);
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004430 if (touchStateIt != mTouchStatesByDisplay.end()) {
4431 const TouchState& touchState = touchStateIt->second;
Linnan Li907ae732023-09-05 17:14:21 +08004432 if (touchState.hasTouchingPointers(args.deviceId) ||
4433 touchState.hasHoveringPointers(args.deviceId)) {
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004434 policyFlags |= POLICY_FLAG_PASS_TO_USER;
4435 }
4436 }
4437 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004438
4439 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004440 ui::Transform displayTransform;
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004441 if (const auto it = mDisplayInfos.find(args.displayId); it != mDisplayInfos.end()) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004442 displayTransform = it->second.transform;
4443 }
4444
Michael Wrightd02c5b62014-02-10 15:10:22 -08004445 mLock.unlock();
4446
4447 MotionEvent event;
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004448 event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC,
4449 args.action, args.actionButton, args.flags, args.edgeFlags,
4450 args.metaState, args.buttonState, args.classification,
4451 displayTransform, args.xPrecision, args.yPrecision,
4452 args.xCursorPosition, args.yCursorPosition, displayTransform,
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004453 args.downTime, args.eventTime, args.getPointerCount(),
4454 args.pointerProperties.data(), args.pointerCoords.data());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004455
4456 policyFlags |= POLICY_FLAG_FILTERED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004457 if (!mPolicy.filterInputEvent(event, policyFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004458 return; // event was consumed by the filter
4459 }
4460
4461 mLock.lock();
4462 }
4463
4464 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004465 std::unique_ptr<MotionEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004466 std::make_unique<MotionEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4467 args.deviceId, args.source, args.displayId,
4468 policyFlags, args.action, args.actionButton,
4469 args.flags, args.metaState, args.buttonState,
4470 args.classification, args.edgeFlags, args.xPrecision,
4471 args.yPrecision, args.xCursorPosition,
4472 args.yCursorPosition, args.downTime,
4473 args.pointerProperties, args.pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004474
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004475 if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4476 IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004477 !mInputFilterEnabled) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004478 const bool isDown = args.action == AMOTION_EVENT_ACTION_DOWN;
Asmita Poddardd9a6cd2023-09-26 15:35:12 +00004479 std::set<InputDeviceUsageSource> sources = getUsageSourcesForMotionArgs(args);
4480 mLatencyTracker.trackListener(args.id, isDown, args.eventTime, args.readTime,
4481 args.deviceId, sources);
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004482 }
4483
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004484 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004485 mLock.unlock();
4486 } // release lock
4487
4488 if (needWake) {
4489 mLooper->wake();
4490 }
4491}
4492
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004493void InputDispatcher::notifySensor(const NotifySensorArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004494 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004495 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4496 " sensorType=%s",
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004497 args.id, args.eventTime, args.deviceId, args.source,
4498 ftl::enum_string(args.sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004499 }
Chris Yef59a2f42020-10-16 12:55:26 -07004500
Antonio Kantekf16f2832021-09-28 04:39:20 +00004501 bool needWake = false;
Chris Yef59a2f42020-10-16 12:55:26 -07004502 { // acquire lock
4503 mLock.lock();
4504
4505 // Just enqueue a new sensor event.
4506 std::unique_ptr<SensorEntry> newEntry =
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004507 std::make_unique<SensorEntry>(args.id, args.eventTime, args.deviceId, args.source,
4508 /* policyFlags=*/0, args.hwTimestamp, args.sensorType,
4509 args.accuracy, args.accuracyChanged, args.values);
Chris Yef59a2f42020-10-16 12:55:26 -07004510
4511 needWake = enqueueInboundEventLocked(std::move(newEntry));
4512 mLock.unlock();
4513 } // release lock
4514
4515 if (needWake) {
4516 mLooper->wake();
4517 }
4518}
4519
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004520void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004521 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004522 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args.eventTime,
4523 args.deviceId, args.isOn);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004524 }
Prabir Pradhana41d2442023-04-20 21:30:40 +00004525 mPolicy.notifyVibratorState(args.deviceId, args.isOn);
Chris Yefb552902021-02-03 17:18:37 -08004526}
4527
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004528bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs& args) {
Jackal Guof9696682018-10-05 12:23:23 +08004529 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004530}
4531
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004532void InputDispatcher::notifySwitch(const NotifySwitchArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004533 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004534 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4535 "switchMask=0x%08x",
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004536 args.eventTime, args.policyFlags, args.switchValues, args.switchMask);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004537 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004538
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004539 uint32_t policyFlags = args.policyFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004540 policyFlags |= POLICY_FLAG_TRUSTED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004541 mPolicy.notifySwitch(args.eventTime, args.switchValues, args.switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004542}
4543
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004544void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004545 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004546 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args.eventTime,
4547 args.deviceId);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004548 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004549
Antonio Kantekf16f2832021-09-28 04:39:20 +00004550 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004551 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004552 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004553
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004554 std::unique_ptr<DeviceResetEntry> newEntry =
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004555 std::make_unique<DeviceResetEntry>(args.id, args.eventTime, args.deviceId);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004556 needWake = enqueueInboundEventLocked(std::move(newEntry));
Siarhei Vishniakou1160ecd2023-06-28 15:57:47 -07004557
4558 for (auto& [_, verifier] : mVerifiersByDisplay) {
4559 verifier.resetDevice(args.deviceId);
4560 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004561 } // release lock
4562
4563 if (needWake) {
4564 mLooper->wake();
4565 }
4566}
4567
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004568void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004569 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004570 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args.eventTime,
4571 args.request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004572 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004573
Antonio Kantekf16f2832021-09-28 04:39:20 +00004574 bool needWake = false;
Prabir Pradhan99987712020-11-10 18:43:05 -08004575 { // acquire lock
4576 std::scoped_lock _l(mLock);
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004577 auto entry =
4578 std::make_unique<PointerCaptureChangedEntry>(args.id, args.eventTime, args.request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004579 needWake = enqueueInboundEventLocked(std::move(entry));
4580 } // release lock
4581
4582 if (needWake) {
4583 mLooper->wake();
4584 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004585}
4586
Prabir Pradhan5735a322022-04-11 17:23:34 +00004587InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* event,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00004588 std::optional<gui::Uid> targetUid,
Prabir Pradhan5735a322022-04-11 17:23:34 +00004589 InputEventInjectionSync syncMode,
4590 std::chrono::milliseconds timeout,
4591 uint32_t policyFlags) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004592 Result<void> eventValidation = validateInputEvent(*event);
4593 if (!eventValidation.ok()) {
4594 LOG(INFO) << "Injection failed: invalid event: " << eventValidation.error();
4595 return InputEventInjectionResult::FAILED;
4596 }
4597
Prabir Pradhan65613802023-02-22 23:36:58 +00004598 if (debugInboundEventDetails()) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004599 LOG(INFO) << __func__ << ": targetUid=" << toString(targetUid, &uidString)
4600 << ", syncMode=" << ftl::enum_string(syncMode) << ", timeout=" << timeout.count()
4601 << "ms, policyFlags=0x" << std::hex << policyFlags << std::dec
4602 << ", event=" << *event;
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004603 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004604 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004605
Prabir Pradhan5735a322022-04-11 17:23:34 +00004606 policyFlags |= POLICY_FLAG_INJECTED | POLICY_FLAG_TRUSTED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004607
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004608 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004609 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4610 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4611 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4612 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4613 // from events that originate from actual hardware.
Siarhei Vishniakouf4043212023-09-18 19:33:03 -07004614 DeviceId resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004615 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004616 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004617 }
4618
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004619 const bool isAsync = syncMode == InputEventInjectionSync::NONE;
4620 auto injectionState = std::make_shared<InjectionState>(targetUid, isAsync);
4621
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004622 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004623 switch (event->getType()) {
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004624 case InputEventType::KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004625 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004626 const int32_t action = incomingKey.getAction();
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004627 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004628 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4629 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4630 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004631 int32_t keyCode = incomingKey.getKeyCode();
4632 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004633 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004634 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004635 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4636 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4637 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004638
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004639 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4640 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004641 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004642
4643 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4644 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004645 mPolicy.interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004646 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4647 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4648 std::to_string(t.duration().count()).c_str());
4649 }
4650 }
4651
4652 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004653 std::unique_ptr<KeyEntry> injectedEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004654 std::make_unique<KeyEntry>(incomingKey.getId(), injectionState,
4655 incomingKey.getEventTime(), resolvedDeviceId,
4656 incomingKey.getSource(), incomingKey.getDisplayId(),
4657 policyFlags, action, flags, keyCode,
4658 incomingKey.getScanCode(), metaState,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004659 incomingKey.getRepeatCount(),
4660 incomingKey.getDownTime());
4661 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004662 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004663 }
4664
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004665 case InputEventType::MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004666 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004667 const bool isPointerEvent =
4668 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4669 // If a pointer event has no displayId specified, inject it to the default display.
4670 const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
4671 ? ADISPLAY_ID_DEFAULT
4672 : event->getDisplayId();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004673 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004674
4675 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004676 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004677 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004678 mPolicy.interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004679 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4680 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4681 std::to_string(t.duration().count()).c_str());
4682 }
4683 }
4684
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004685 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4686 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4687 }
4688
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004689 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004690 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004691 const size_t pointerCount = motionEvent.getPointerCount();
4692 const std::vector<PointerProperties>
4693 pointerProperties(motionEvent.getPointerProperties(),
4694 motionEvent.getPointerProperties() + pointerCount);
4695
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004696 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004697 std::unique_ptr<MotionEntry> injectedEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004698 std::make_unique<MotionEntry>(motionEvent.getId(), injectionState,
4699 *sampleEventTimes, resolvedDeviceId,
4700 motionEvent.getSource(), displayId, policyFlags,
4701 motionEvent.getAction(),
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004702 motionEvent.getActionButton(), flags,
4703 motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004704 motionEvent.getButtonState(),
4705 motionEvent.getClassification(),
4706 motionEvent.getEdgeFlags(),
4707 motionEvent.getXPrecision(),
4708 motionEvent.getYPrecision(),
4709 motionEvent.getRawXCursorPosition(),
4710 motionEvent.getRawYCursorPosition(),
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004711 motionEvent.getDownTime(), pointerProperties,
4712 std::vector<PointerCoords>(samplePointerCoords,
4713 samplePointerCoords +
4714 pointerCount));
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004715 transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004716 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004717 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004718 sampleEventTimes += 1;
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004719 samplePointerCoords += motionEvent.getPointerCount();
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004720 std::unique_ptr<MotionEntry> nextInjectedEntry = std::make_unique<
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004721 MotionEntry>(motionEvent.getId(), injectionState, *sampleEventTimes,
4722 resolvedDeviceId, motionEvent.getSource(), displayId,
4723 policyFlags, motionEvent.getAction(),
4724 motionEvent.getActionButton(), flags,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004725 motionEvent.getMetaState(), motionEvent.getButtonState(),
4726 motionEvent.getClassification(), motionEvent.getEdgeFlags(),
4727 motionEvent.getXPrecision(), motionEvent.getYPrecision(),
4728 motionEvent.getRawXCursorPosition(),
4729 motionEvent.getRawYCursorPosition(), motionEvent.getDownTime(),
4730 pointerProperties,
4731 std::vector<PointerCoords>(samplePointerCoords,
4732 samplePointerCoords +
4733 pointerCount));
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004734 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
4735 motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004736 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004737 }
4738 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004739 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004740
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004741 default:
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004742 LOG(WARNING) << "Cannot inject " << ftl::enum_string(event->getType()) << " events";
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004743 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004744 }
4745
Michael Wrightd02c5b62014-02-10 15:10:22 -08004746 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004747 while (!injectedEntries.empty()) {
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08004748 if (DEBUG_INJECTION) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004749 LOG(INFO) << "Injecting " << injectedEntries.front()->getDescription();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08004750 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004751 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004752 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004753 }
4754
4755 mLock.unlock();
4756
4757 if (needWake) {
4758 mLooper->wake();
4759 }
4760
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004761 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004762 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004763 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004764
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004765 if (syncMode == InputEventInjectionSync::NONE) {
4766 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004767 } else {
4768 for (;;) {
4769 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004770 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004771 break;
4772 }
4773
4774 nsecs_t remainingTimeout = endTime - now();
4775 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004776 if (DEBUG_INJECTION) {
4777 ALOGD("injectInputEvent - Timed out waiting for injection result "
4778 "to become available.");
4779 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004780 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004781 break;
4782 }
4783
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004784 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004785 }
4786
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004787 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4788 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004789 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004790 if (DEBUG_INJECTION) {
4791 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4792 injectionState->pendingForegroundDispatches);
4793 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004794 nsecs_t remainingTimeout = endTime - now();
4795 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004796 if (DEBUG_INJECTION) {
4797 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4798 "dispatches to finish.");
4799 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004800 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004801 break;
4802 }
4803
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004804 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004805 }
4806 }
4807 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004808 } // release lock
4809
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004810 if (DEBUG_INJECTION) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004811 LOG(INFO) << "injectInputEvent - Finished with result "
4812 << ftl::enum_string(injectionResult);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004813 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004814
4815 return injectionResult;
4816}
4817
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004818std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004819 std::array<uint8_t, 32> calculatedHmac;
4820 std::unique_ptr<VerifiedInputEvent> result;
4821 switch (event.getType()) {
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004822 case InputEventType::KEY: {
Gang Wange9087892020-01-07 12:17:14 -05004823 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4824 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4825 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004826 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004827 break;
4828 }
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004829 case InputEventType::MOTION: {
Gang Wange9087892020-01-07 12:17:14 -05004830 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4831 VerifiedMotionEvent verifiedMotionEvent =
4832 verifiedMotionEventFromMotionEvent(motionEvent);
4833 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004834 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004835 break;
4836 }
4837 default: {
4838 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4839 return nullptr;
4840 }
4841 }
4842 if (calculatedHmac == INVALID_HMAC) {
4843 return nullptr;
4844 }
tyiu1573a672023-02-21 22:38:32 +00004845 if (0 != CRYPTO_memcmp(calculatedHmac.data(), event.getHmac().data(), calculatedHmac.size())) {
Gang Wange9087892020-01-07 12:17:14 -05004846 return nullptr;
4847 }
4848 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004849}
4850
Prabir Pradhan24047542023-11-02 17:14:59 +00004851void InputDispatcher::setInjectionResult(const EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004852 InputEventInjectionResult injectionResult) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004853 if (!entry.injectionState) {
4854 // Not an injected event.
4855 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004856 }
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004857
4858 InjectionState& injectionState = *entry.injectionState;
4859 if (DEBUG_INJECTION) {
4860 LOG(INFO) << "Setting input event injection result to "
4861 << ftl::enum_string(injectionResult);
4862 }
4863
4864 if (injectionState.injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
4865 // Log the outcome since the injector did not wait for the injection result.
4866 switch (injectionResult) {
4867 case InputEventInjectionResult::SUCCEEDED:
4868 ALOGV("Asynchronous input event injection succeeded.");
4869 break;
4870 case InputEventInjectionResult::TARGET_MISMATCH:
4871 ALOGV("Asynchronous input event injection target mismatch.");
4872 break;
4873 case InputEventInjectionResult::FAILED:
4874 ALOGW("Asynchronous input event injection failed.");
4875 break;
4876 case InputEventInjectionResult::TIMED_OUT:
4877 ALOGW("Asynchronous input event injection timed out.");
4878 break;
4879 case InputEventInjectionResult::PENDING:
4880 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4881 break;
4882 }
4883 }
4884
4885 injectionState.injectionResult = injectionResult;
4886 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004887}
4888
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004889void InputDispatcher::transformMotionEntryForInjectionLocked(
4890 MotionEntry& entry, const ui::Transform& injectedTransform) const {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004891 // Input injection works in the logical display coordinate space, but the input pipeline works
4892 // display space, so we need to transform the injected events accordingly.
4893 const auto it = mDisplayInfos.find(entry.displayId);
4894 if (it == mDisplayInfos.end()) return;
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004895 const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004896
Prabir Pradhand9a2ebe2022-07-20 19:25:13 +00004897 if (entry.xCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
4898 entry.yCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
4899 const vec2 cursor =
4900 MotionEvent::calculateTransformedXY(entry.source, transformToDisplay,
4901 {entry.xCursorPosition, entry.yCursorPosition});
4902 entry.xCursorPosition = cursor.x;
4903 entry.yCursorPosition = cursor.y;
4904 }
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004905 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
Prabir Pradhan8e6ce222022-02-24 09:08:54 -08004906 entry.pointerCoords[i] =
4907 MotionEvent::calculateTransformedCoords(entry.source, transformToDisplay,
4908 entry.pointerCoords[i]);
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004909 }
4910}
4911
Prabir Pradhan24047542023-11-02 17:14:59 +00004912void InputDispatcher::incrementPendingForegroundDispatches(const EventEntry& entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004913 if (entry.injectionState) {
4914 entry.injectionState->pendingForegroundDispatches += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004915 }
4916}
4917
Prabir Pradhan24047542023-11-02 17:14:59 +00004918void InputDispatcher::decrementPendingForegroundDispatches(const EventEntry& entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004919 if (entry.injectionState) {
4920 entry.injectionState->pendingForegroundDispatches -= 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004921
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004922 if (entry.injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004923 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004924 }
4925 }
4926}
4927
chaviw98318de2021-05-19 16:45:23 -05004928const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004929 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004930 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004931 auto it = mWindowHandlesByDisplay.find(displayId);
4932 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004933}
4934
chaviw98318de2021-05-19 16:45:23 -05004935sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
Prabir Pradhan16463382023-10-12 23:03:19 +00004936 const sp<IBinder>& windowHandleToken, std::optional<int32_t> displayId) const {
arthurhungbe737672020-06-24 12:29:21 +08004937 if (windowHandleToken == nullptr) {
4938 return nullptr;
4939 }
4940
Prabir Pradhan16463382023-10-12 23:03:19 +00004941 if (!displayId) {
4942 // Look through all displays.
4943 for (auto& it : mWindowHandlesByDisplay) {
4944 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4945 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
4946 if (windowHandle->getToken() == windowHandleToken) {
4947 return windowHandle;
4948 }
Arthur Hungb92218b2018-08-14 12:00:21 +08004949 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004950 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07004951 return nullptr;
4952 }
4953
Prabir Pradhan16463382023-10-12 23:03:19 +00004954 // Only look through the requested display.
4955 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(*displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004956 if (windowHandle->getToken() == windowHandleToken) {
4957 return windowHandle;
4958 }
4959 }
4960 return nullptr;
4961}
4962
chaviw98318de2021-05-19 16:45:23 -05004963sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4964 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004965 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004966 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4967 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004968 if (handle->getId() == windowHandle->getId() &&
4969 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004970 if (windowHandle->getInfo()->displayId != it.first) {
4971 ALOGE("Found window %s in display %" PRId32
4972 ", but it should belong to display %" PRId32,
4973 windowHandle->getName().c_str(), it.first,
4974 windowHandle->getInfo()->displayId);
4975 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004976 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004977 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004978 }
4979 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004980 return nullptr;
4981}
4982
chaviw98318de2021-05-19 16:45:23 -05004983sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004984 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4985 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004986}
4987
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00004988ui::Transform InputDispatcher::getTransformLocked(int32_t displayId) const {
4989 auto displayInfoIt = mDisplayInfos.find(displayId);
4990 return displayInfoIt != mDisplayInfos.end() ? displayInfoIt->second.transform
4991 : kIdentityTransform;
4992}
4993
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07004994bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& window,
4995 const MotionEntry& motionEntry) const {
4996 const WindowInfo& info = *window->getInfo();
4997
4998 // Skip spy window targets that are not valid for targeted injection.
4999 if (const auto err = verifyTargetedInjection(window, motionEntry); err) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005000 return false;
5001 }
5002
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005003 if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
5004 ALOGI("Not sending touch event to %s because it is paused", window->getName().c_str());
5005 return false;
5006 }
5007
5008 if (info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL)) {
5009 ALOGW("Not sending touch gesture to %s because it has config NO_INPUT_CHANNEL",
5010 window->getName().c_str());
5011 return false;
5012 }
5013
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005014 std::shared_ptr<Connection> connection = getConnectionLocked(window->getToken());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005015 if (connection == nullptr) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005016 ALOGW("Not sending touch to %s because there's no corresponding connection",
5017 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005018 return false;
5019 }
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005020
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005021 if (!connection->responsive) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005022 ALOGW("Not sending touch to %s because it is not responsive", window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005023 return false;
5024 }
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005025
5026 // Drop events that can't be trusted due to occlusion
5027 const auto [x, y] = resolveTouchedPosition(motionEntry);
5028 TouchOcclusionInfo occlusionInfo = computeTouchOcclusionInfoLocked(window, x, y);
5029 if (!isTouchTrustedLocked(occlusionInfo)) {
5030 if (DEBUG_TOUCH_OCCLUSION) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00005031 ALOGD("Stack of obscuring windows during untrusted touch (%.1f, %.1f):", x, y);
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005032 for (const auto& log : occlusionInfo.debugInfo) {
5033 ALOGD("%s", log.c_str());
5034 }
5035 }
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00005036 ALOGW("Dropping untrusted touch event due to %s/%s", occlusionInfo.obscuringPackage.c_str(),
5037 occlusionInfo.obscuringUid.toString().c_str());
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005038 return false;
5039 }
5040
5041 // Drop touch events if requested by input feature
5042 if (shouldDropInput(motionEntry, window)) {
5043 return false;
5044 }
5045
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005046 return true;
5047}
5048
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005049std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
5050 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005051 auto connectionIt = mConnectionsByToken.find(token);
5052 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07005053 return nullptr;
5054 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005055 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07005056}
5057
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005058void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05005059 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
5060 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005061 // Remove all handles on a display if there are no windows left.
5062 mWindowHandlesByDisplay.erase(displayId);
5063 return;
5064 }
5065
5066 // Since we compare the pointer of input window handles across window updates, we need
5067 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05005068 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
5069 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
5070 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07005071 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005072 }
5073
chaviw98318de2021-05-19 16:45:23 -05005074 std::vector<sp<WindowInfoHandle>> newHandles;
5075 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05005076 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005077 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005078 const bool noInputChannel =
Prabir Pradhan51e7db02022-02-07 06:02:57 -08005079 info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005080 const bool canReceiveInput =
5081 !info->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) ||
5082 !info->inputConfig.test(WindowInfo::InputConfig::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005083 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07005084 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005085 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07005086 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005087 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005088 }
5089
5090 if (info->displayId != displayId) {
5091 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
5092 handle->getName().c_str(), displayId, info->displayId);
5093 continue;
5094 }
5095
Robert Carredd13602020-04-13 17:24:34 -07005096 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
5097 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05005098 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005099 oldHandle->updateFrom(handle);
5100 newHandles.push_back(oldHandle);
5101 } else {
5102 newHandles.push_back(handle);
5103 }
5104 }
5105
5106 // Insert or replace
5107 mWindowHandlesByDisplay[displayId] = newHandles;
5108}
5109
Arthur Hungb92218b2018-08-14 12:00:21 +08005110/**
5111 * Called from InputManagerService, update window handle list by displayId that can receive input.
5112 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
5113 * If set an empty list, remove all handles from the specific display.
5114 * For focused handle, check if need to change and send a cancel event to previous one.
5115 * For removed handle, check if need to send a cancel event if already in touch.
5116 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00005117void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05005118 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005119 if (DEBUG_FOCUS) {
5120 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05005121 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005122 windowList += iwh->getName() + " ";
5123 }
5124 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
5125 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005126
Prabir Pradhand65552b2021-10-07 11:23:50 -07005127 // Check preconditions for new input windows
chaviw98318de2021-05-19 16:45:23 -05005128 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07005129 const WindowInfo& info = *window->getInfo();
5130
5131 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
Prabir Pradhan51e7db02022-02-07 06:02:57 -08005132 const bool noInputWindow = info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005133 if (noInputWindow && window->getToken() != nullptr) {
5134 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
5135 window->getName().c_str());
5136 window->releaseChannel();
5137 }
Prabir Pradhand65552b2021-10-07 11:23:50 -07005138
Prabir Pradhan5c85e052021-12-22 02:27:12 -08005139 // Ensure all spy windows are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005140 LOG_ALWAYS_FATAL_IF(info.isSpy() &&
5141 !info.inputConfig.test(
5142 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhan5c85e052021-12-22 02:27:12 -08005143 "%s has feature SPY, but is not a trusted overlay.",
5144 window->getName().c_str());
5145
Prabir Pradhand65552b2021-10-07 11:23:50 -07005146 // Ensure all stylus interceptors are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005147 LOG_ALWAYS_FATAL_IF(info.interceptsStylus() &&
5148 !info.inputConfig.test(
5149 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhand65552b2021-10-07 11:23:50 -07005150 "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
5151 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005152 }
5153
Arthur Hung72d8dc32020-03-28 00:48:39 +00005154 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05005155 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005156
chaviw98318de2021-05-19 16:45:23 -05005157 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005158
chaviw98318de2021-05-19 16:45:23 -05005159 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00005160
Vishnu Nairc519ff72021-01-21 08:23:08 -08005161 std::optional<FocusResolver::FocusChanges> changes =
5162 mFocusResolver.setInputWindows(displayId, windowHandles);
5163 if (changes) {
5164 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00005165 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005166
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005167 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5168 mTouchStatesByDisplay.find(displayId);
5169 if (stateIt != mTouchStatesByDisplay.end()) {
5170 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00005171 for (size_t i = 0; i < state.windows.size();) {
5172 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005173 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07005174 LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName()
5175 << " in display %" << displayId;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005176 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00005177 getInputChannelLocked(touchedWindow.windowHandle->getToken());
5178 if (touchedInputChannel != nullptr) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00005179 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Arthur Hung72d8dc32020-03-28 00:48:39 +00005180 "touched window was removed");
5181 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005182 // Since we are about to drop the touch, cancel the events for the wallpaper as
5183 // well.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005184 if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005185 touchedWindow.windowHandle->getInfo()->inputConfig.test(
5186 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005187 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
Arthur Hungc539dbb2022-12-08 07:45:36 +00005188 synthesizeCancelationEventsForWindowLocked(wallpaper, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005189 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005190 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005191 state.windows.erase(state.windows.begin() + i);
5192 } else {
5193 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005194 }
5195 }
arthurhungb89ccb02020-12-30 16:19:01 +08005196
arthurhung6d4bed92021-03-17 11:59:33 +08005197 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08005198 // could just clear the state here.
Arthur Hung3915c1f2022-05-31 07:17:17 +00005199 if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId &&
arthurhung6d4bed92021-03-17 11:59:33 +08005200 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08005201 windowHandles.end()) {
Arthur Hung3915c1f2022-05-31 07:17:17 +00005202 ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str());
5203 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08005204 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08005205 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005206 }
Arthur Hung25e2af12020-03-26 12:58:37 +00005207
Arthur Hung72d8dc32020-03-28 00:48:39 +00005208 // Release information for windows that are no longer present.
5209 // This ensures that unused input channels are released promptly.
5210 // Otherwise, they might stick around until the window handle is destroyed
5211 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05005212 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005213 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00005214 if (DEBUG_FOCUS) {
5215 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00005216 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005217 oldWindowHandle->releaseChannel();
Arthur Hung25e2af12020-03-26 12:58:37 +00005218 }
chaviw291d88a2019-02-14 10:33:58 -08005219 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005220}
5221
5222void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07005223 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005224 if (DEBUG_FOCUS) {
5225 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
5226 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
5227 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005228 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005229 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07005230 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005231 } // release lock
5232
5233 // Wake up poll loop since it may need to make new input dispatching choices.
5234 mLooper->wake();
5235}
5236
Vishnu Nair599f1412021-06-21 10:39:58 -07005237void InputDispatcher::setFocusedApplicationLocked(
5238 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
5239 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
5240 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
5241
5242 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
5243 return; // This application is already focused. No need to wake up or change anything.
5244 }
5245
5246 // Set the new application handle.
5247 if (inputApplicationHandle != nullptr) {
5248 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
5249 } else {
5250 mFocusedApplicationHandlesByDisplay.erase(displayId);
5251 }
5252
5253 // No matter what the old focused application was, stop waiting on it because it is
5254 // no longer focused.
5255 resetNoFocusedWindowTimeoutLocked();
5256}
5257
Tiger Huang721e26f2018-07-24 22:26:19 +08005258/**
5259 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
5260 * the display not specified.
5261 *
5262 * We track any unreleased events for each window. If a window loses the ability to receive the
5263 * released event, we will send a cancel event to it. So when the focused display is changed, we
5264 * cancel all the unreleased display-unspecified events for the focused window on the old focused
5265 * display. The display-specified events won't be affected.
5266 */
5267void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005268 if (DEBUG_FOCUS) {
5269 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
5270 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005271 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005272 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08005273
5274 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005275 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08005276 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005277 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005278 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07005279 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08005280 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005281 CancelationOptions
Michael Wrightfb04fd52022-11-24 22:31:11 +00005282 options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005283 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005284 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08005285 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
5286 }
5287 }
5288 mFocusedDisplayId = displayId;
5289
Chris Ye3c2d6f52020-08-09 10:39:48 -07005290 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08005291 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00005292 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08005293
Vishnu Nairad321cd2020-08-20 16:40:21 -07005294 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08005295 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005296 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005297 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08005298 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08005299 }
5300 }
5301 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005302 } // release lock
5303
5304 // Wake up poll loop since it may need to make new input dispatching choices.
5305 mLooper->wake();
5306}
5307
Michael Wrightd02c5b62014-02-10 15:10:22 -08005308void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005309 if (DEBUG_FOCUS) {
5310 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
5311 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005312
5313 bool changed;
5314 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005315 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005316
5317 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
5318 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005319 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005320 }
5321
5322 if (mDispatchEnabled && !enabled) {
5323 resetAndDropEverythingLocked("dispatcher is being disabled");
5324 }
5325
5326 mDispatchEnabled = enabled;
5327 mDispatchFrozen = frozen;
5328 changed = true;
5329 } else {
5330 changed = false;
5331 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005332 } // release lock
5333
5334 if (changed) {
5335 // Wake up poll loop since it may need to make new input dispatching choices.
5336 mLooper->wake();
5337 }
5338}
5339
5340void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005341 if (DEBUG_FOCUS) {
5342 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
5343 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005344
5345 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005346 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005347
5348 if (mInputFilterEnabled == enabled) {
5349 return;
5350 }
5351
5352 mInputFilterEnabled = enabled;
5353 resetAndDropEverythingLocked("input filter is being enabled or disabled");
5354 } // release lock
5355
5356 // Wake up poll loop since there might be work to do to drop everything.
5357 mLooper->wake();
5358}
5359
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005360bool InputDispatcher::setInTouchMode(bool inTouchMode, gui::Pid pid, gui::Uid uid,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00005361 bool hasPermission, int32_t displayId) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00005362 bool needWake = false;
5363 {
5364 std::scoped_lock lock(mLock);
Antonio Kantek15beb512022-06-13 22:35:41 +00005365 ALOGD_IF(DEBUG_TOUCH_MODE,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005366 "Request to change touch mode to %s (calling pid=%s, uid=%s, "
Antonio Kantek15beb512022-06-13 22:35:41 +00005367 "hasPermission=%s, target displayId=%d, mTouchModePerDisplay[displayId]=%s)",
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005368 toString(inTouchMode), pid.toString().c_str(), uid.toString().c_str(),
5369 toString(hasPermission), displayId,
Antonio Kantek15beb512022-06-13 22:35:41 +00005370 mTouchModePerDisplay.count(displayId) == 0
5371 ? "not set"
5372 : std::to_string(mTouchModePerDisplay[displayId]).c_str());
5373
Antonio Kantek15beb512022-06-13 22:35:41 +00005374 auto touchModeIt = mTouchModePerDisplay.find(displayId);
5375 if (touchModeIt != mTouchModePerDisplay.end() && touchModeIt->second == inTouchMode) {
Antonio Kantekea47acb2021-12-23 12:41:25 -08005376 return false;
Antonio Kantekf16f2832021-09-28 04:39:20 +00005377 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005378 if (!hasPermission) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005379 if (!focusedWindowIsOwnedByLocked(pid, uid) &&
5380 !recentWindowsAreOwnedByLocked(pid, uid)) {
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005381 ALOGD("Touch mode switch rejected, caller (pid=%s, uid=%s) doesn't own the focused "
Antonio Kantek48710e42022-03-24 14:19:30 -07005382 "window nor none of the previously interacted window",
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005383 pid.toString().c_str(), uid.toString().c_str());
Antonio Kantekea47acb2021-12-23 12:41:25 -08005384 return false;
5385 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00005386 }
Antonio Kantek15beb512022-06-13 22:35:41 +00005387 mTouchModePerDisplay[displayId] = inTouchMode;
5388 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode,
5389 displayId);
Antonio Kantekf16f2832021-09-28 04:39:20 +00005390 needWake = enqueueInboundEventLocked(std::move(entry));
5391 } // release lock
5392
5393 if (needWake) {
5394 mLooper->wake();
5395 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005396 return true;
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08005397}
5398
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005399bool InputDispatcher::focusedWindowIsOwnedByLocked(gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005400 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
5401 if (focusedToken == nullptr) {
5402 return false;
5403 }
5404 sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken);
5405 return isWindowOwnedBy(windowHandle, pid, uid);
5406}
5407
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005408bool InputDispatcher::recentWindowsAreOwnedByLocked(gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005409 return std::find_if(mInteractionConnectionTokens.begin(), mInteractionConnectionTokens.end(),
5410 [&](const sp<IBinder>& connectionToken) REQUIRES(mLock) {
5411 const sp<WindowInfoHandle> windowHandle =
5412 getWindowHandleLocked(connectionToken);
5413 return isWindowOwnedBy(windowHandle, pid, uid);
5414 }) != mInteractionConnectionTokens.end();
5415}
5416
Bernardo Rufinoea97d182020-08-19 14:43:14 +01005417void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
5418 if (opacity < 0 || opacity > 1) {
5419 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
5420 return;
5421 }
5422
5423 std::scoped_lock lock(mLock);
5424 mMaximumObscuringOpacityForTouch = opacity;
5425}
5426
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005427std::tuple<TouchState*, TouchedWindow*, int32_t /*displayId*/>
5428InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) {
Arthur Hungabbb9d82021-09-01 14:52:30 +00005429 for (auto& [displayId, state] : mTouchStatesByDisplay) {
5430 for (TouchedWindow& w : state.windows) {
5431 if (w.windowHandle->getToken() == token) {
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005432 return std::make_tuple(&state, &w, displayId);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005433 }
5434 }
5435 }
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005436 return std::make_tuple(nullptr, nullptr, ADISPLAY_ID_DEFAULT);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005437}
5438
arthurhungb89ccb02020-12-30 16:19:01 +08005439bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5440 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08005441 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005442 if (DEBUG_FOCUS) {
5443 ALOGD("Trivial transfer to same window.");
5444 }
chaviwfbe5d9c2018-12-26 12:23:37 -08005445 return true;
5446 }
5447
Michael Wrightd02c5b62014-02-10 15:10:22 -08005448 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005449 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005450
Arthur Hungabbb9d82021-09-01 14:52:30 +00005451 // Find the target touch state and touched window by fromToken.
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005452 auto [state, touchedWindow, displayId] = findTouchStateWindowAndDisplayLocked(fromToken);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005453
Arthur Hungabbb9d82021-09-01 14:52:30 +00005454 if (state == nullptr || touchedWindow == nullptr) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005455 ALOGD("Touch transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005456 return false;
5457 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005458 std::set<int32_t> deviceIds = touchedWindow->getTouchingDeviceIds();
5459 if (deviceIds.size() != 1) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07005460 LOG(INFO) << "Can't transfer touch. Currently touching devices: " << dumpSet(deviceIds)
5461 << " for window: " << touchedWindow->dump();
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005462 return false;
5463 }
5464 const int32_t deviceId = *deviceIds.begin();
Arthur Hungabbb9d82021-09-01 14:52:30 +00005465
Arthur Hungabbb9d82021-09-01 14:52:30 +00005466 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
5467 if (toWindowHandle == nullptr) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005468 ALOGW("Cannot transfer touch because to window not found.");
Arthur Hungabbb9d82021-09-01 14:52:30 +00005469 return false;
5470 }
5471
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005472 if (DEBUG_FOCUS) {
5473 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00005474 touchedWindow->windowHandle->getName().c_str(),
5475 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005476 }
5477
Arthur Hungabbb9d82021-09-01 14:52:30 +00005478 // Erase old window.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005479 ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags;
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005480 std::bitset<MAX_POINTER_ID + 1> pointerIds = touchedWindow->getTouchingPointers(deviceId);
Arthur Hungc539dbb2022-12-08 07:45:36 +00005481 sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
Arthur Hungabbb9d82021-09-01 14:52:30 +00005482 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005483
Arthur Hungabbb9d82021-09-01 14:52:30 +00005484 // Add new window.
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00005485 nsecs_t downTimeInTarget = now();
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005486 ftl::Flags<InputTarget::Flags> newTargetFlags =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00005487 oldTargetFlags & (InputTarget::Flags::SPLIT);
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005488 if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005489 newTargetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005490 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00005491 state->addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags,
5492 deviceId, pointerIds, downTimeInTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005493
Arthur Hungabbb9d82021-09-01 14:52:30 +00005494 // Store the dragging window.
5495 if (isDragDrop) {
Arthur Hungb75c2aa2022-07-15 09:35:36 +00005496 if (pointerIds.count() != 1) {
5497 ALOGW("The drag and drop cannot be started when there is no pointer or more than 1"
5498 " pointer on the window.");
Arthur Hung54745652022-04-20 07:17:41 +00005499 return false;
5500 }
Arthur Hungb75c2aa2022-07-15 09:35:36 +00005501 // Track the pointer id for drag window and generate the drag state.
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08005502 const size_t id = firstMarkedBit(pointerIds);
Arthur Hung54745652022-04-20 07:17:41 +00005503 mDragState = std::make_unique<DragState>(toWindowHandle, id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005504 }
5505
Arthur Hungabbb9d82021-09-01 14:52:30 +00005506 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005507 std::shared_ptr<Connection> fromConnection = getConnectionLocked(fromToken);
5508 std::shared_ptr<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005509 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005510 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005511 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5512 "transferring touch from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005513 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Arthur Hungc539dbb2022-12-08 07:45:36 +00005514 synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection,
5515 newTargetFlags);
5516
5517 // Check if the wallpaper window should deliver the corresponding event.
5518 transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005519 *state, deviceId, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005520 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005521 } // release lock
5522
5523 // Wake up poll loop since it may need to make new input dispatching choices.
5524 mLooper->wake();
5525 return true;
5526}
5527
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005528/**
5529 * Get the touched foreground window on the given display.
5530 * Return null if there are no windows touched on that display, or if more than one foreground
5531 * window is being touched.
5532 */
5533sp<WindowInfoHandle> InputDispatcher::findTouchedForegroundWindowLocked(int32_t displayId) const {
5534 auto stateIt = mTouchStatesByDisplay.find(displayId);
5535 if (stateIt == mTouchStatesByDisplay.end()) {
5536 ALOGI("No touch state on display %" PRId32, displayId);
5537 return nullptr;
5538 }
5539
5540 const TouchState& state = stateIt->second;
5541 sp<WindowInfoHandle> touchedForegroundWindow;
5542 // If multiple foreground windows are touched, return nullptr
5543 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005544 if (window.targetFlags.test(InputTarget::Flags::FOREGROUND)) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005545 if (touchedForegroundWindow != nullptr) {
5546 ALOGI("Two or more foreground windows: %s and %s",
5547 touchedForegroundWindow->getName().c_str(),
5548 window.windowHandle->getName().c_str());
5549 return nullptr;
5550 }
5551 touchedForegroundWindow = window.windowHandle;
5552 }
5553 }
5554 return touchedForegroundWindow;
5555}
5556
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005557// Binder call
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005558bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken, int32_t displayId) {
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005559 sp<IBinder> fromToken;
5560 { // acquire lock
5561 std::scoped_lock _l(mLock);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005562 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005563 if (toWindowHandle == nullptr) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005564 ALOGW("Could not find window associated with token=%p on display %" PRId32,
5565 destChannelToken.get(), displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005566 return false;
5567 }
5568
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005569 sp<WindowInfoHandle> from = findTouchedForegroundWindowLocked(displayId);
5570 if (from == nullptr) {
5571 ALOGE("Could not find a source window in %s for %p", __func__, destChannelToken.get());
5572 return false;
5573 }
5574
5575 fromToken = from->getToken();
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005576 } // release lock
5577
5578 return transferTouchFocus(fromToken, destChannelToken);
5579}
5580
Michael Wrightd02c5b62014-02-10 15:10:22 -08005581void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005582 if (DEBUG_FOCUS) {
5583 ALOGD("Resetting and dropping all events (%s).", reason);
5584 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005585
Michael Wrightfb04fd52022-11-24 22:31:11 +00005586 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005587 synthesizeCancelationEventsForAllConnectionsLocked(options);
5588
5589 resetKeyRepeatLocked();
5590 releasePendingEventLocked();
5591 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005592 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005593
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005594 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005595 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005596}
5597
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005598void InputDispatcher::logDispatchStateLocked() const {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005599 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005600 dumpDispatchStateLocked(dump);
5601
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005602 std::istringstream stream(dump);
5603 std::string line;
5604
5605 while (std::getline(stream, line, '\n')) {
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07005606 ALOGI("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005607 }
5608}
5609
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005610std::string InputDispatcher::dumpPointerCaptureStateLocked() const {
Prabir Pradhan99987712020-11-10 18:43:05 -08005611 std::string dump;
5612
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005613 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5614 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005615
5616 std::string windowName = "None";
5617 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005618 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005619 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5620 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5621 : "token has capture without window";
5622 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005623 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005624
5625 return dump;
5626}
5627
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005628void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005629 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5630 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5631 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005632 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005633
Tiger Huang721e26f2018-07-24 22:26:19 +08005634 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5635 dump += StringPrintf(INDENT "FocusedApplications:\n");
5636 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5637 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005638 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005639 const std::chrono::duration timeout =
5640 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005641 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005642 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005643 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005644 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005645 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005646 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005647 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005648
Vishnu Nairc519ff72021-01-21 08:23:08 -08005649 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005650 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005651
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005652 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005653 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005654 for (const auto& [displayId, state] : mTouchStatesByDisplay) {
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -08005655 std::string touchStateDump = addLinePrefix(state.dump(), INDENT2);
5656 dump += INDENT2 + std::to_string(displayId) + " : " + touchStateDump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005657 }
5658 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005659 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005660 }
5661
arthurhung6d4bed92021-03-17 11:59:33 +08005662 if (mDragState) {
5663 dump += StringPrintf(INDENT "DragState:\n");
5664 mDragState->dump(dump, INDENT2);
5665 }
5666
Arthur Hungb92218b2018-08-14 12:00:21 +08005667 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005668 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5669 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5670 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5671 const auto& displayInfo = it->second;
5672 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5673 displayInfo.logicalHeight);
5674 displayInfo.transform.dump(dump, "transform", INDENT4);
5675 } else {
5676 dump += INDENT2 "No DisplayInfo found!\n";
5677 }
5678
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005679 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005680 dump += INDENT2 "Windows:\n";
5681 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005682 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5683 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005684
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005685 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005686 "inputConfig=%s, alpha=%.2f, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005687 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005688 "applicationInfo.name=%s, "
5689 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005690 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005691 i, windowInfo->name.c_str(), windowInfo->id,
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005692 windowInfo->displayId,
5693 windowInfo->inputConfig.string().c_str(),
Chavi Weingarten7f019192023-08-08 20:39:01 +00005694 windowInfo->alpha, windowInfo->frame.left,
5695 windowInfo->frame.top, windowInfo->frame.right,
5696 windowInfo->frame.bottom, windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005697 windowInfo->applicationInfo.name.c_str(),
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07005698 binderToString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005699 dump += dumpRegion(windowInfo->touchableRegion);
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005700 dump += StringPrintf(", ownerPid=%s, ownerUid=%s, dispatchingTimeout=%" PRId64
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005701 "ms, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005702 "touchOcclusionMode=%s\n",
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005703 windowInfo->ownerPid.toString().c_str(),
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00005704 windowInfo->ownerUid.toString().c_str(),
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005705 millis(windowInfo->dispatchingTimeout),
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07005706 binderToString(windowInfo->token).c_str(),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005707 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005708 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005709 }
5710 } else {
5711 dump += INDENT2 "Windows: <none>\n";
5712 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005713 }
5714 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005715 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005716 }
5717
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005718 if (!mGlobalMonitorsByDisplay.empty()) {
5719 for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
5720 dump += StringPrintf(INDENT "Global monitors on display %d:\n", displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00005721 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005722 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005723 } else {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005724 dump += INDENT "Global Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005725 }
5726
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005727 const nsecs_t currentTime = now();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005728
5729 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005730 if (!mRecentQueue.empty()) {
5731 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Prabir Pradhan24047542023-11-02 17:14:59 +00005732 for (const std::shared_ptr<const EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005733 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005734 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005735 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005736 }
5737 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005738 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005739 }
5740
5741 // Dump event currently being dispatched.
5742 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005743 dump += INDENT "PendingEvent:\n";
5744 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005745 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005746 dump += StringPrintf(", age=%" PRId64 "ms\n",
5747 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005748 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005749 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005750 }
5751
5752 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005753 if (!mInboundQueue.empty()) {
5754 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Prabir Pradhan24047542023-11-02 17:14:59 +00005755 for (const std::shared_ptr<const EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005756 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005757 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005758 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005759 }
5760 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005761 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005762 }
5763
Prabir Pradhancef936d2021-07-21 16:17:52 +00005764 if (!mCommandQueue.empty()) {
5765 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5766 } else {
5767 dump += INDENT "CommandQueue: <empty>\n";
5768 }
5769
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005770 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005771 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005772 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005773 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005774 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005775 connection->inputChannel->getFd().get(),
5776 connection->getInputChannelName().c_str(),
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005777 connection->getWindowName().c_str(),
5778 ftl::enum_string(connection->status).c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005779 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005780
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005781 if (!connection->outboundQueue.empty()) {
5782 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5783 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005784 dump += dumpQueue(connection->outboundQueue, currentTime);
5785
Michael Wrightd02c5b62014-02-10 15:10:22 -08005786 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005787 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005788 }
5789
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005790 if (!connection->waitQueue.empty()) {
5791 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5792 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005793 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005794 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005795 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005796 }
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -07005797 std::stringstream inputStateDump;
5798 inputStateDump << connection->inputState;
5799 if (!isEmpty(inputStateDump)) {
5800 dump += INDENT3 "InputState: ";
5801 dump += inputStateDump.str() + "\n";
5802 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005803 }
5804 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005805 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005806 }
5807
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07005808 dump += "input_flags::remove_app_switch_drops() = ";
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07005809 dump += toString(REMOVE_APP_SWITCH_DROPS);
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07005810 dump += "\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005811 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005812 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5813 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005814 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005815 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005816 }
5817
Antonio Kantek15beb512022-06-13 22:35:41 +00005818 if (!mTouchModePerDisplay.empty()) {
5819 dump += INDENT "TouchModePerDisplay:\n";
5820 for (const auto& [displayId, touchMode] : mTouchModePerDisplay) {
5821 dump += StringPrintf(INDENT2 "Display: %" PRId32 " TouchMode: %s\n", displayId,
5822 std::to_string(touchMode).c_str());
5823 }
5824 } else {
5825 dump += INDENT "TouchModePerDisplay: <none>\n";
5826 }
5827
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005828 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005829 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5830 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5831 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005832 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005833 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005834}
5835
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005836void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00005837 const size_t numMonitors = monitors.size();
5838 for (size_t i = 0; i < numMonitors; i++) {
5839 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005840 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005841 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5842 dump += "\n";
5843 }
5844}
5845
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005846class LooperEventCallback : public LooperCallback {
5847public:
5848 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5849 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5850
5851private:
5852 std::function<int(int events)> mCallback;
5853};
5854
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005855Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005856 if (DEBUG_CHANNEL_CREATION) {
5857 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5858 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005859
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005860 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005861 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005862 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005863
5864 if (result) {
5865 return base::Error(result) << "Failed to open input channel pair with name " << name;
5866 }
5867
Michael Wrightd02c5b62014-02-10 15:10:22 -08005868 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005869 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005870 const sp<IBinder>& token = serverChannel->getConnectionToken();
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005871 auto&& fd = serverChannel->getFd();
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005872 std::shared_ptr<Connection> connection =
5873 std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/false,
5874 mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005875
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005876 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5877 ALOGE("Created a new connection, but the token %p is already known", token.get());
5878 }
5879 mConnectionsByToken.emplace(token, connection);
5880
5881 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5882 this, std::placeholders::_1, token);
5883
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005884 mLooper->addFd(fd.get(), 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005885 nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005886 } // release lock
5887
5888 // Wake the looper because some connections have changed.
5889 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005890 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005891}
5892
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005893Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005894 const std::string& name,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005895 gui::Pid pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005896 std::shared_ptr<InputChannel> serverChannel;
5897 std::unique_ptr<InputChannel> clientChannel;
5898 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5899 if (result) {
5900 return base::Error(result) << "Failed to open input channel pair with name " << name;
5901 }
5902
Michael Wright3dd60e22019-03-27 22:06:44 +00005903 { // acquire lock
5904 std::scoped_lock _l(mLock);
5905
5906 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005907 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5908 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005909 }
5910
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005911 std::shared_ptr<Connection> connection =
5912 std::make_shared<Connection>(serverChannel, /*monitor=*/true, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005913 const sp<IBinder>& token = serverChannel->getConnectionToken();
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005914 auto&& fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005915
5916 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5917 ALOGE("Created a new connection, but the token %p is already known", token.get());
5918 }
5919 mConnectionsByToken.emplace(token, connection);
5920 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5921 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005922
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005923 mGlobalMonitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005924
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005925 mLooper->addFd(fd.get(), 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005926 nullptr);
Michael Wright3dd60e22019-03-27 22:06:44 +00005927 }
Garfield Tan15601662020-09-22 15:32:38 -07005928
Michael Wright3dd60e22019-03-27 22:06:44 +00005929 // Wake the looper because some connections have changed.
5930 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005931 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005932}
5933
Garfield Tan15601662020-09-22 15:32:38 -07005934status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005935 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005936 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005937
Harry Cutts33476232023-01-30 19:57:29 +00005938 status_t status = removeInputChannelLocked(connectionToken, /*notify=*/false);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005939 if (status) {
5940 return status;
5941 }
5942 } // release lock
5943
5944 // Wake the poll loop because removing the connection may have changed the current
5945 // synchronization state.
5946 mLooper->wake();
5947 return OK;
5948}
5949
Garfield Tan15601662020-09-22 15:32:38 -07005950status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5951 bool notify) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005952 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005953 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005954 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005955 return BAD_VALUE;
5956 }
5957
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005958 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005959
Michael Wrightd02c5b62014-02-10 15:10:22 -08005960 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005961 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005962 }
5963
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005964 mLooper->removeFd(connection->inputChannel->getFd().get());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005965
5966 nsecs_t currentTime = now();
5967 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5968
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005969 connection->status = Connection::Status::ZOMBIE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005970 return OK;
5971}
5972
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005973void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005974 for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
5975 auto& [displayId, monitors] = *it;
5976 std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
5977 return monitor.inputChannel->getConnectionToken() == connectionToken;
5978 });
Michael Wright3dd60e22019-03-27 22:06:44 +00005979
Michael Wright3dd60e22019-03-27 22:06:44 +00005980 if (monitors.empty()) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005981 it = mGlobalMonitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005982 } else {
5983 ++it;
5984 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005985 }
5986}
5987
Michael Wright3dd60e22019-03-27 22:06:44 +00005988status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005989 std::scoped_lock _l(mLock);
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00005990 return pilferPointersLocked(token);
5991}
Michael Wright3dd60e22019-03-27 22:06:44 +00005992
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00005993status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005994 const std::shared_ptr<InputChannel> requestingChannel = getInputChannelLocked(token);
5995 if (!requestingChannel) {
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07005996 LOG(WARNING)
5997 << "Attempted to pilfer pointers from an un-registered channel or invalid token";
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005998 return BAD_VALUE;
Michael Wright3dd60e22019-03-27 22:06:44 +00005999 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006000
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07006001 auto [statePtr, windowPtr, displayId] = findTouchStateWindowAndDisplayLocked(token);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006002 if (statePtr == nullptr || windowPtr == nullptr) {
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006003 LOG(WARNING)
6004 << "Attempted to pilfer points from a channel without any on-going pointer streams."
6005 " Ignoring.";
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006006 return BAD_VALUE;
6007 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006008 std::set<int32_t> deviceIds = windowPtr->getTouchingDeviceIds();
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07006009 if (deviceIds.empty()) {
6010 LOG(WARNING) << "Can't pilfer: no touching devices in window: " << windowPtr->dump();
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006011 return BAD_VALUE;
6012 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006013
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006014 for (const DeviceId deviceId : deviceIds) {
6015 TouchState& state = *statePtr;
6016 TouchedWindow& window = *windowPtr;
6017 // Send cancel events to all the input channels we're stealing from.
6018 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6019 "input channel stole pointer stream");
6020 options.deviceId = deviceId;
6021 options.displayId = displayId;
6022 std::bitset<MAX_POINTER_ID + 1> pointerIds = window.getTouchingPointers(deviceId);
6023 options.pointerIds = pointerIds;
6024 std::string canceledWindows;
6025 for (const TouchedWindow& w : state.windows) {
6026 const std::shared_ptr<InputChannel> channel =
6027 getInputChannelLocked(w.windowHandle->getToken());
6028 if (channel != nullptr && channel->getConnectionToken() != token) {
6029 synthesizeCancelationEventsForInputChannelLocked(channel, options);
6030 canceledWindows += canceledWindows.empty() ? "[" : ", ";
6031 canceledWindows += channel->getName();
6032 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006033 }
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006034 canceledWindows += canceledWindows.empty() ? "[]" : "]";
6035 LOG(INFO) << "Channel " << requestingChannel->getName()
6036 << " is stealing input gesture for device " << deviceId << " from "
6037 << canceledWindows;
6038
6039 // Prevent the gesture from being sent to any other windows.
6040 // This only blocks relevant pointers to be sent to other windows
6041 window.addPilferingPointers(deviceId, pointerIds);
6042
6043 state.cancelPointersForWindowsExcept(deviceId, pointerIds, token);
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006044 }
Michael Wright3dd60e22019-03-27 22:06:44 +00006045 return OK;
6046}
6047
Prabir Pradhan99987712020-11-10 18:43:05 -08006048void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
6049 { // acquire lock
6050 std::scoped_lock _l(mLock);
6051 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05006052 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08006053 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
6054 windowHandle != nullptr ? windowHandle->getName().c_str()
6055 : "token without window");
6056 }
6057
Vishnu Nairc519ff72021-01-21 08:23:08 -08006058 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08006059 if (focusedToken != windowToken) {
6060 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
6061 enabled ? "enable" : "disable");
6062 return;
6063 }
6064
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006065 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006066 ALOGW("Ignoring request to %s Pointer Capture: "
6067 "window has %s requested pointer capture.",
6068 enabled ? "enable" : "disable", enabled ? "already" : "not");
6069 return;
6070 }
6071
Christine Franksb768bb42021-11-29 12:11:31 -08006072 if (enabled) {
6073 if (std::find(mIneligibleDisplaysForPointerCapture.begin(),
6074 mIneligibleDisplaysForPointerCapture.end(),
6075 mFocusedDisplayId) != mIneligibleDisplaysForPointerCapture.end()) {
6076 ALOGW("Ignoring request to enable Pointer Capture: display is not eligible");
6077 return;
6078 }
6079 }
6080
Prabir Pradhan99987712020-11-10 18:43:05 -08006081 setPointerCaptureLocked(enabled);
6082 } // release lock
6083
6084 // Wake the thread to process command entries.
6085 mLooper->wake();
6086}
6087
Christine Franksb768bb42021-11-29 12:11:31 -08006088void InputDispatcher::setDisplayEligibilityForPointerCapture(int32_t displayId, bool isEligible) {
6089 { // acquire lock
6090 std::scoped_lock _l(mLock);
6091 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
6092 if (!isEligible) {
6093 mIneligibleDisplaysForPointerCapture.push_back(displayId);
6094 }
6095 } // release lock
6096}
6097
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006098std::optional<gui::Pid> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006099 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00006100 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006101 if (monitor.inputChannel->getConnectionToken() == token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006102 return monitor.pid;
Michael Wright3dd60e22019-03-27 22:06:44 +00006103 }
6104 }
6105 }
6106 return std::nullopt;
6107}
6108
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006109std::shared_ptr<Connection> InputDispatcher::getConnectionLocked(
6110 const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07006111 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006112 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08006113 }
6114
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00006115 for (const auto& [token, connection] : mConnectionsByToken) {
6116 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006117 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006118 }
6119 }
Robert Carr4e670e52018-08-15 13:26:12 -07006120
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006121 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006122}
6123
Siarhei Vishniakouad991402020-10-28 11:40:09 -05006124std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006125 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakouad991402020-10-28 11:40:09 -05006126 if (connection == nullptr) {
6127 return "<nullptr>";
6128 }
6129 return connection->getInputChannelName();
6130}
6131
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006132void InputDispatcher::removeConnectionLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006133 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00006134 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07006135}
6136
Prabir Pradhancef936d2021-07-21 16:17:52 +00006137void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006138 const std::shared_ptr<Connection>& connection,
6139 uint32_t seq, bool handled,
6140 nsecs_t consumeTime) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006141 // Handle post-event policy actions.
Prabir Pradhan24047542023-11-02 17:14:59 +00006142 std::unique_ptr<const KeyEntry> fallbackKeyEntry;
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006143
6144 { // Start critical section
6145 auto dispatchEntryIt =
6146 std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6147 [seq](auto& e) { return e->seq == seq; });
6148 if (dispatchEntryIt == connection->waitQueue.end()) {
6149 return;
6150 }
6151
6152 DispatchEntry& dispatchEntry = **dispatchEntryIt;
6153
6154 const nsecs_t eventDuration = finishTime - dispatchEntry.deliveryTime;
6155 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
6156 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
6157 ns2ms(eventDuration), dispatchEntry.eventEntry->getDescription().c_str());
6158 }
6159 if (shouldReportFinishedEvent(dispatchEntry, *connection)) {
6160 mLatencyTracker.trackFinishedEvent(dispatchEntry.eventEntry->id,
6161 connection->inputChannel->getConnectionToken(),
6162 dispatchEntry.deliveryTime, consumeTime, finishTime);
6163 }
6164
6165 if (dispatchEntry.eventEntry->type == EventEntry::Type::KEY) {
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006166 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*(dispatchEntry.eventEntry));
6167 fallbackKeyEntry =
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006168 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006169 }
6170 } // End critical section: The -LockedInterruptable methods may have released the lock.
Prabir Pradhancef936d2021-07-21 16:17:52 +00006171
6172 // Dequeue the event and start the next cycle.
6173 // Because the lock might have been released, it is possible that the
6174 // contents of the wait queue to have been drained, so we need to double-check
6175 // a few things.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006176 auto entryIt = std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6177 [seq](auto& e) { return e->seq == seq; });
6178 if (entryIt != connection->waitQueue.end()) {
6179 std::unique_ptr<DispatchEntry> dispatchEntry = std::move(*entryIt);
6180 connection->waitQueue.erase(entryIt);
6181
Prabir Pradhancef936d2021-07-21 16:17:52 +00006182 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
6183 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
6184 if (!connection->responsive) {
6185 connection->responsive = isConnectionResponsive(*connection);
6186 if (connection->responsive) {
6187 // The connection was unresponsive, and now it's responsive.
6188 processConnectionResponsiveLocked(*connection);
6189 }
6190 }
6191 traceWaitQueueLength(*connection);
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006192 if (fallbackKeyEntry && connection->status == Connection::Status::NORMAL) {
6193 const InputTarget target{.inputChannel = connection->inputChannel,
6194 .flags = dispatchEntry->targetFlags};
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006195 enqueueDispatchEntryLocked(connection, std::move(fallbackKeyEntry), target);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006196 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006197 releaseDispatchEntry(std::move(dispatchEntry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00006198 }
6199
6200 // Start the next dispatch cycle for this connection.
6201 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006202}
6203
Prabir Pradhancef936d2021-07-21 16:17:52 +00006204void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
6205 const sp<IBinder>& newToken) {
6206 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
6207 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006208 mPolicy.notifyFocusChanged(oldToken, newToken);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006209 };
6210 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006211}
6212
Prabir Pradhancef936d2021-07-21 16:17:52 +00006213void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
6214 auto command = [this, token, x, y]() REQUIRES(mLock) {
6215 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006216 mPolicy.notifyDropWindow(token, x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006217 };
6218 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08006219}
6220
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006221void InputDispatcher::onAnrLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006222 if (connection == nullptr) {
6223 LOG_ALWAYS_FATAL("Caller must check for nullness");
6224 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006225 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
6226 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006227 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006228 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006229 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006230 return;
6231 }
6232 /**
6233 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
6234 * may not be the one that caused the timeout to occur. One possibility is that window timeout
6235 * has changed. This could cause newer entries to time out before the already dispatched
6236 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
6237 * processes the events linearly. So providing information about the oldest entry seems to be
6238 * most useful.
6239 */
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006240 DispatchEntry& oldestEntry = *connection->waitQueue.front();
6241 const nsecs_t currentWait = now() - oldestEntry.deliveryTime;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006242 std::string reason =
6243 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006244 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006245 ns2ms(currentWait),
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006246 oldestEntry.eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006247 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06006248 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006249
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006250 processConnectionUnresponsiveLocked(*connection, std::move(reason));
6251
6252 // Stop waking up for events on this connection, it is already unresponsive
6253 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006254}
6255
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05006256void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
6257 std::string reason =
6258 StringPrintf("%s does not have a focused window", application->getName().c_str());
6259 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006260
Yabin Cui8eb9c552023-06-08 18:05:07 +00006261 auto command = [this, app = std::move(application)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006262 scoped_unlock unlock(mLock);
Yabin Cuiced952f2023-06-09 21:12:51 +00006263 mPolicy.notifyNoFocusedWindowAnr(app);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006264 };
6265 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00006266}
6267
chaviw98318de2021-05-19 16:45:23 -05006268void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006269 const std::string& reason) {
6270 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
6271 updateLastAnrStateLocked(windowLabel, reason);
6272}
6273
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05006274void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
6275 const std::string& reason) {
6276 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006277 updateLastAnrStateLocked(windowLabel, reason);
6278}
6279
6280void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
6281 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006282 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07006283 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006284 struct tm tm;
6285 localtime_r(&t, &tm);
6286 char timestr[64];
6287 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006288 mLastAnrState.clear();
6289 mLastAnrState += INDENT "ANR:\n";
6290 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006291 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
6292 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006293 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006294}
6295
Prabir Pradhancef936d2021-07-21 16:17:52 +00006296void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
Prabir Pradhan24047542023-11-02 17:14:59 +00006297 const KeyEntry& entry) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006298 const KeyEvent event = createKeyEvent(entry);
6299 nsecs_t delay = 0;
6300 { // release lock
6301 scoped_unlock unlock(mLock);
6302 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00006303 delay = mPolicy.interceptKeyBeforeDispatching(focusedWindowToken, event, entry.policyFlags);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006304 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
6305 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
6306 std::to_string(t.duration().count()).c_str());
6307 }
6308 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08006309
6310 if (delay < 0) {
Michael Wright5caf55a2022-11-24 22:31:42 +00006311 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00006312 } else if (delay == 0) {
Michael Wright5caf55a2022-11-24 22:31:42 +00006313 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006314 } else {
Michael Wright5caf55a2022-11-24 22:31:42 +00006315 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006316 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006317 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006318}
6319
Prabir Pradhancef936d2021-07-21 16:17:52 +00006320void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006321 std::optional<gui::Pid> pid,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006322 std::string reason) {
Yabin Cui8eb9c552023-06-08 18:05:07 +00006323 auto command = [this, token, pid, r = std::move(reason)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006324 scoped_unlock unlock(mLock);
Yabin Cuiced952f2023-06-09 21:12:51 +00006325 mPolicy.notifyWindowUnresponsive(token, pid, r);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006326 };
6327 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006328}
6329
Prabir Pradhanedd96402022-02-15 01:46:16 -08006330void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006331 std::optional<gui::Pid> pid) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08006332 auto command = [this, token, pid]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006333 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006334 mPolicy.notifyWindowResponsive(token, pid);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006335 };
6336 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006337}
6338
6339/**
6340 * Tell the policy that a connection has become unresponsive so that it can start ANR.
6341 * Check whether the connection of interest is a monitor or a window, and add the corresponding
6342 * command entry to the command queue.
6343 */
6344void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
6345 std::string reason) {
6346 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006347 std::optional<gui::Pid> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006348 if (connection.monitor) {
6349 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
6350 reason.c_str());
Prabir Pradhanedd96402022-02-15 01:46:16 -08006351 pid = findMonitorPidByTokenLocked(connectionToken);
6352 } else {
6353 // The connection is a window
6354 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
6355 reason.c_str());
6356 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6357 if (handle != nullptr) {
6358 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006359 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006360 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08006361 sendWindowUnresponsiveCommandLocked(connectionToken, pid, std::move(reason));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006362}
6363
6364/**
6365 * Tell the policy that a connection has become responsive so that it can stop ANR.
6366 */
6367void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
6368 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006369 std::optional<gui::Pid> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006370 if (connection.monitor) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08006371 pid = findMonitorPidByTokenLocked(connectionToken);
6372 } else {
6373 // The connection is a window
6374 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6375 if (handle != nullptr) {
6376 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006377 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006378 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08006379 sendWindowResponsiveCommandLocked(connectionToken, pid);
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006380}
6381
Prabir Pradhan24047542023-11-02 17:14:59 +00006382std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptable(
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006383 const std::shared_ptr<Connection>& connection, DispatchEntry& dispatchEntry,
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006384 const KeyEntry& keyEntry, bool handled) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006385 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006386 if (!handled) {
6387 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006388 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006389 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006390 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006391 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006392
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006393 // Get the fallback key state.
6394 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006395 int32_t originalKeyCode = keyEntry.keyCode;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006396 std::optional<int32_t> fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006397 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006398 connection->inputState.removeFallbackKey(originalKeyCode);
6399 }
6400
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006401 if (handled || !dispatchEntry.hasForegroundTarget()) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006402 // If the application handles the original key for which we previously
6403 // generated a fallback or if the window is not a foreground window,
6404 // then cancel the associated fallback key, if any.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006405 if (fallbackKeyCode) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006406 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006407 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6408 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
6409 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6410 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
6411 keyEntry.policyFlags);
6412 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006413 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006414 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006415
6416 mLock.unlock();
6417
Prabir Pradhana41d2442023-04-20 21:30:40 +00006418 if (const auto unhandledKeyFallback =
6419 mPolicy.dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
6420 event, keyEntry.policyFlags);
6421 unhandledKeyFallback) {
6422 event = *unhandledKeyFallback;
6423 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006424
6425 mLock.lock();
6426
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006427 // Cancel the fallback key.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006428 if (*fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00006429 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006430 "application handled the original non-fallback key "
6431 "or is no longer a foreground target, "
6432 "canceling previously dispatched fallback key");
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006433 options.keyCode = *fallbackKeyCode;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006434 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006435 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006436 connection->inputState.removeFallbackKey(originalKeyCode);
6437 }
6438 } else {
6439 // If the application did not handle a non-fallback key, first check
6440 // that we are in a good state to perform unhandled key event processing
6441 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006442 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006443 if (!fallbackKeyCode && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006444 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6445 ALOGD("Unhandled key event: Skipping unhandled key event processing "
6446 "since this is not an initial down. "
6447 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6448 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6449 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006450 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006451 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006452
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006453 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006454 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6455 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
6456 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6457 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6458 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006459 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006460
6461 mLock.unlock();
6462
Prabir Pradhana41d2442023-04-20 21:30:40 +00006463 bool fallback = false;
6464 if (auto fb = mPolicy.dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
6465 event, keyEntry.policyFlags);
6466 fb) {
6467 fallback = true;
6468 event = *fb;
6469 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006470
6471 mLock.lock();
6472
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08006473 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006474 connection->inputState.removeFallbackKey(originalKeyCode);
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006475 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006476 }
6477
6478 // Latch the fallback keycode for this key on an initial down.
6479 // The fallback keycode cannot change at any other point in the lifecycle.
6480 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006481 if (fallback) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006482 *fallbackKeyCode = event.getKeyCode();
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006483 } else {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006484 *fallbackKeyCode = AKEYCODE_UNKNOWN;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006485 }
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006486 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006487 }
6488
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006489 ALOG_ASSERT(fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006490
6491 // Cancel the fallback key if the policy decides not to send it anymore.
6492 // We will continue to dispatch the key to the policy but we will no
6493 // longer dispatch a fallback key to the application.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006494 if (*fallbackKeyCode != AKEYCODE_UNKNOWN &&
6495 (!fallback || *fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006496 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6497 if (fallback) {
6498 ALOGD("Unhandled key event: Policy requested to send key %d"
6499 "as a fallback for %d, but on the DOWN it had requested "
6500 "to send %d instead. Fallback canceled.",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006501 event.getKeyCode(), originalKeyCode, *fallbackKeyCode);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006502 } else {
6503 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6504 "but on the DOWN it had requested to send %d. "
6505 "Fallback canceled.",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006506 originalKeyCode, *fallbackKeyCode);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006507 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006508 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006509
Michael Wrightfb04fd52022-11-24 22:31:11 +00006510 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006511 "canceling fallback, policy no longer desires it");
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006512 options.keyCode = *fallbackKeyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006513 synthesizeCancelationEventsForConnectionLocked(connection, options);
6514
6515 fallback = false;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006516 *fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006517 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006518 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006519 }
6520 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006521
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006522 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6523 {
6524 std::string msg;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006525 const std::map<int32_t, int32_t>& fallbackKeys =
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006526 connection->inputState.getFallbackKeys();
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006527 for (const auto& [key, value] : fallbackKeys) {
6528 msg += StringPrintf(", %d->%d", key, value);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006529 }
6530 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6531 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006532 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006533 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006534
6535 if (fallback) {
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006536 // Return the fallback key that we want dispatched to the channel.
6537 std::unique_ptr<KeyEntry> newEntry =
6538 std::make_unique<KeyEntry>(mIdGenerator.nextId(), keyEntry.injectionState,
6539 event.getEventTime(), event.getDeviceId(),
6540 event.getSource(), event.getDisplayId(),
6541 keyEntry.policyFlags, keyEntry.action,
6542 event.getFlags() | AKEY_EVENT_FLAG_FALLBACK,
6543 *fallbackKeyCode, event.getScanCode(),
6544 event.getMetaState(), event.getRepeatCount(),
6545 event.getDownTime());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006546 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6547 ALOGD("Unhandled key event: Dispatching fallback key. "
6548 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006549 originalKeyCode, *fallbackKeyCode, keyEntry.metaState);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006550 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006551 return newEntry;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006552 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006553 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6554 ALOGD("Unhandled key event: No fallback key.");
6555 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006556
6557 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006558 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006559 }
6560 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006561 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08006562}
6563
Michael Wrightd02c5b62014-02-10 15:10:22 -08006564void InputDispatcher::traceInboundQueueLengthLocked() {
6565 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006566 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006567 }
6568}
6569
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006570void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006571 if (ATRACE_ENABLED()) {
6572 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006573 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6574 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006575 }
6576}
6577
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006578void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006579 if (ATRACE_ENABLED()) {
6580 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006581 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6582 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006583 }
6584}
6585
Siarhei Vishniakou5e20f272023-06-08 17:24:44 -07006586void InputDispatcher::dump(std::string& dump) const {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006587 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006588
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006589 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006590 dumpDispatchStateLocked(dump);
6591
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006592 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006593 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006594 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006595 }
6596}
6597
6598void InputDispatcher::monitor() {
6599 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006600 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006601 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006602 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006603}
6604
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006605/**
6606 * Wake up the dispatcher and wait until it processes all events and commands.
6607 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6608 * this method can be safely called from any thread, as long as you've ensured that
6609 * the work you are interested in completing has already been queued.
6610 */
Siarhei Vishniakoua66d65e2023-06-16 10:32:51 -07006611bool InputDispatcher::waitForIdle() const {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006612 /**
6613 * Timeout should represent the longest possible time that a device might spend processing
6614 * events and commands.
6615 */
6616 constexpr std::chrono::duration TIMEOUT = 100ms;
6617 std::unique_lock lock(mLock);
6618 mLooper->wake();
6619 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6620 return result == std::cv_status::no_timeout;
6621}
6622
Vishnu Naire798b472020-07-23 13:52:21 -07006623/**
6624 * Sets focus to the window identified by the token. This must be called
6625 * after updating any input window handles.
6626 *
6627 * Params:
6628 * request.token - input channel token used to identify the window that should gain focus.
6629 * request.focusedToken - the token that the caller expects currently to be focused. If the
6630 * specified token does not match the currently focused window, this request will be dropped.
6631 * If the specified focused token matches the currently focused window, the call will succeed.
6632 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6633 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6634 * when requesting the focus change. This determines which request gets
6635 * precedence if there is a focus change request from another source such as pointer down.
6636 */
Vishnu Nair958da932020-08-21 17:12:37 -07006637void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6638 { // acquire lock
6639 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006640 std::optional<FocusResolver::FocusChanges> changes =
6641 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6642 if (changes) {
6643 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006644 }
6645 } // release lock
6646 // Wake up poll loop since it may need to make new input dispatching choices.
6647 mLooper->wake();
6648}
6649
Vishnu Nairc519ff72021-01-21 08:23:08 -08006650void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6651 if (changes.oldFocus) {
6652 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006653 if (focusedInputChannel) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00006654 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006655 "focus left window");
6656 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Harry Cutts33476232023-01-30 19:57:29 +00006657 enqueueFocusEventLocked(changes.oldFocus, /*hasFocus=*/false, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006658 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006659 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006660 if (changes.newFocus) {
Siarhei Vishniakouc033dfb2023-10-03 10:45:16 -07006661 resetNoFocusedWindowTimeoutLocked();
Harry Cutts33476232023-01-30 19:57:29 +00006662 enqueueFocusEventLocked(changes.newFocus, /*hasFocus=*/true, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006663 }
6664
Prabir Pradhan99987712020-11-10 18:43:05 -08006665 // If a window has pointer capture, then it must have focus. We need to ensure that this
6666 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6667 // If the window loses focus before it loses pointer capture, then the window can be in a state
6668 // where it has pointer capture but not focus, violating the contract. Therefore we must
6669 // dispatch the pointer capture event before the focus event. Since focus events are added to
6670 // the front of the queue (above), we add the pointer capture event to the front of the queue
6671 // after the focus events are added. This ensures the pointer capture event ends up at the
6672 // front.
6673 disablePointerCaptureForcedLocked();
6674
Vishnu Nairc519ff72021-01-21 08:23:08 -08006675 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006676 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006677 }
6678}
Vishnu Nair958da932020-08-21 17:12:37 -07006679
Prabir Pradhan99987712020-11-10 18:43:05 -08006680void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006681 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006682 return;
6683 }
6684
6685 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6686
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006687 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006688 setPointerCaptureLocked(false);
6689 }
6690
6691 if (!mWindowTokenWithPointerCapture) {
6692 // No need to send capture changes because no window has capture.
6693 return;
6694 }
6695
6696 if (mPendingEvent != nullptr) {
6697 // Move the pending event to the front of the queue. This will give the chance
6698 // for the pending event to be dropped if it is a captured event.
6699 mInboundQueue.push_front(mPendingEvent);
6700 mPendingEvent = nullptr;
6701 }
6702
6703 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006704 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006705 mInboundQueue.push_front(std::move(entry));
6706}
6707
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006708void InputDispatcher::setPointerCaptureLocked(bool enable) {
6709 mCurrentPointerCaptureRequest.enable = enable;
6710 mCurrentPointerCaptureRequest.seq++;
6711 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006712 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006713 mPolicy.setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006714 };
6715 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006716}
6717
Vishnu Nair599f1412021-06-21 10:39:58 -07006718void InputDispatcher::displayRemoved(int32_t displayId) {
6719 { // acquire lock
6720 std::scoped_lock _l(mLock);
6721 // Set an empty list to remove all handles from the specific display.
Harry Cutts101ee9b2023-07-06 18:04:14 +00006722 setInputWindowsLocked(/*windowInfoHandles=*/{}, displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006723 setFocusedApplicationLocked(displayId, nullptr);
6724 // Call focus resolver to clean up stale requests. This must be called after input windows
6725 // have been removed for the removed display.
6726 mFocusResolver.displayRemoved(displayId);
Christine Franksb768bb42021-11-29 12:11:31 -08006727 // Reset pointer capture eligibility, regardless of previous state.
6728 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
Antonio Kantek15beb512022-06-13 22:35:41 +00006729 // Remove the associated touch mode state.
6730 mTouchModePerDisplay.erase(displayId);
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07006731 mVerifiersByDisplay.erase(displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006732 } // release lock
6733
6734 // Wake up poll loop since it may need to make new input dispatching choices.
6735 mLooper->wake();
6736}
6737
Patrick Williamsd828f302023-04-28 17:52:08 -05006738void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update) {
chaviw15fab6f2021-06-07 14:15:52 -05006739 // The listener sends the windows as a flattened array. Separate the windows by display for
6740 // more convenient parsing.
6741 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
Patrick Williamsd828f302023-04-28 17:52:08 -05006742 for (const auto& info : update.windowInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006743 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07006744 handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
chaviw15fab6f2021-06-07 14:15:52 -05006745 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006746
6747 { // acquire lock
6748 std::scoped_lock _l(mLock);
Prabir Pradhan814fe082022-07-22 20:22:18 +00006749
6750 // Ensure that we have an entry created for all existing displays so that if a displayId has
6751 // no windows, we can tell that the windows were removed from the display.
6752 for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
6753 handlesPerDisplay[displayId];
6754 }
6755
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006756 mDisplayInfos.clear();
Patrick Williamsd828f302023-04-28 17:52:08 -05006757 for (const auto& displayInfo : update.displayInfos) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006758 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6759 }
6760
6761 for (const auto& [displayId, handles] : handlesPerDisplay) {
6762 setInputWindowsLocked(handles, displayId);
6763 }
Patrick Williams9464b2c2023-05-23 11:22:04 -05006764
6765 if (update.vsyncId < mWindowInfosVsyncId) {
6766 ALOGE("Received out of order window infos update. Last update vsync id: %" PRId64
6767 ", current update vsync id: %" PRId64,
6768 mWindowInfosVsyncId, update.vsyncId);
6769 }
6770 mWindowInfosVsyncId = update.vsyncId;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006771 }
6772 // Wake up poll loop since it may need to make new input dispatching choices.
6773 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006774}
6775
Vishnu Nair062a8672021-09-03 16:07:44 -07006776bool InputDispatcher::shouldDropInput(
6777 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006778 if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
6779 (windowHandle->getInfo()->inputConfig.test(
6780 WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
Vishnu Nair062a8672021-09-03 16:07:44 -07006781 isWindowObscuredLocked(windowHandle))) {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006782 ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on "
6783 "display %" PRId32 ".",
Vishnu Nair062a8672021-09-03 16:07:44 -07006784 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006785 windowHandle->getInfo()->inputConfig.string().c_str(),
Vishnu Nair062a8672021-09-03 16:07:44 -07006786 windowHandle->getInfo()->displayId);
6787 return true;
6788 }
6789 return false;
6790}
6791
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006792void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
Patrick Williamsd828f302023-04-28 17:52:08 -05006793 const gui::WindowInfosUpdate& update) {
6794 mDispatcher.onWindowInfosChanged(update);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006795}
6796
Arthur Hungdfd528e2021-12-08 13:23:04 +00006797void InputDispatcher::cancelCurrentTouch() {
6798 {
6799 std::scoped_lock _l(mLock);
6800 ALOGD("Canceling all ongoing pointer gestures on all displays.");
Michael Wrightfb04fd52022-11-24 22:31:11 +00006801 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Arthur Hungdfd528e2021-12-08 13:23:04 +00006802 "cancel current touch");
6803 synthesizeCancelationEventsForAllConnectionsLocked(options);
6804
6805 mTouchStatesByDisplay.clear();
Arthur Hungdfd528e2021-12-08 13:23:04 +00006806 }
6807 // Wake up poll loop since there might be work to do.
6808 mLooper->wake();
6809}
6810
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08006811void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout) {
6812 std::scoped_lock _l(mLock);
6813 mMonitorDispatchingTimeout = timeout;
6814}
6815
Arthur Hungc539dbb2022-12-08 07:45:36 +00006816void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
6817 const sp<WindowInfoHandle>& oldWindowHandle,
6818 const sp<WindowInfoHandle>& newWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006819 TouchState& state, int32_t deviceId, int32_t pointerId,
Siarhei Vishniakoubf880522023-05-01 11:03:22 -07006820 std::vector<InputTarget>& targets) const {
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08006821 std::bitset<MAX_POINTER_ID + 1> pointerIds;
6822 pointerIds.set(pointerId);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006823 const bool oldHasWallpaper = oldWindowHandle->getInfo()->inputConfig.test(
6824 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6825 const bool newHasWallpaper = targetFlags.test(InputTarget::Flags::FOREGROUND) &&
6826 newWindowHandle->getInfo()->inputConfig.test(
6827 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6828 const sp<WindowInfoHandle> oldWallpaper =
6829 oldHasWallpaper ? state.getWallpaperWindow() : nullptr;
6830 const sp<WindowInfoHandle> newWallpaper =
6831 newHasWallpaper ? findWallpaperWindowBelow(newWindowHandle) : nullptr;
6832 if (oldWallpaper == newWallpaper) {
6833 return;
6834 }
6835
6836 if (oldWallpaper != nullptr) {
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08006837 const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper);
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006838 addPointerWindowTargetLocked(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT,
6839 oldTouchedWindow.targetFlags, pointerIds,
6840 oldTouchedWindow.getDownTimeInTarget(deviceId), targets);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006841 state.removeTouchingPointerFromWindow(deviceId, pointerId, oldWallpaper);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006842 }
6843
6844 if (newWallpaper != nullptr) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006845 state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::SLIPPERY_ENTER,
6846 InputTarget::Flags::WINDOW_IS_OBSCURED |
Arthur Hungc539dbb2022-12-08 07:45:36 +00006847 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006848 deviceId, pointerIds);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006849 }
6850}
6851
6852void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags,
6853 ftl::Flags<InputTarget::Flags> newTargetFlags,
6854 const sp<WindowInfoHandle> fromWindowHandle,
6855 const sp<WindowInfoHandle> toWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006856 TouchState& state, int32_t deviceId,
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08006857 std::bitset<MAX_POINTER_ID + 1> pointerIds) {
Arthur Hungc539dbb2022-12-08 07:45:36 +00006858 const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
6859 fromWindowHandle->getInfo()->inputConfig.test(
6860 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6861 const bool newHasWallpaper = newTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
6862 toWindowHandle->getInfo()->inputConfig.test(
6863 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6864
6865 const sp<WindowInfoHandle> oldWallpaper =
6866 oldHasWallpaper ? state.getWallpaperWindow() : nullptr;
6867 const sp<WindowInfoHandle> newWallpaper =
6868 newHasWallpaper ? findWallpaperWindowBelow(toWindowHandle) : nullptr;
6869 if (oldWallpaper == newWallpaper) {
6870 return;
6871 }
6872
6873 if (oldWallpaper != nullptr) {
6874 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6875 "transferring touch focus to another window");
6876 state.removeWindowByToken(oldWallpaper->getToken());
6877 synthesizeCancelationEventsForWindowLocked(oldWallpaper, options);
6878 }
6879
6880 if (newWallpaper != nullptr) {
6881 nsecs_t downTimeInTarget = now();
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006882 ftl::Flags<InputTarget::Flags> wallpaperFlags = oldTargetFlags & InputTarget::Flags::SPLIT;
Arthur Hungc539dbb2022-12-08 07:45:36 +00006883 wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED |
6884 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006885 state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
6886 deviceId, pointerIds, downTimeInTarget);
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006887 std::shared_ptr<Connection> wallpaperConnection =
6888 getConnectionLocked(newWallpaper->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00006889 if (wallpaperConnection != nullptr) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006890 std::shared_ptr<Connection> toConnection =
6891 getConnectionLocked(toWindowHandle->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00006892 toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState);
6893 synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, wallpaperConnection,
6894 wallpaperFlags);
6895 }
6896 }
6897}
6898
6899sp<WindowInfoHandle> InputDispatcher::findWallpaperWindowBelow(
6900 const sp<WindowInfoHandle>& windowHandle) const {
6901 const std::vector<sp<WindowInfoHandle>>& windowHandles =
6902 getWindowHandlesLocked(windowHandle->getInfo()->displayId);
6903 bool foundWindow = false;
6904 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
6905 if (!foundWindow && otherHandle != windowHandle) {
6906 continue;
6907 }
6908 if (windowHandle == otherHandle) {
6909 foundWindow = true;
6910 continue;
6911 }
6912
6913 if (otherHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::IS_WALLPAPER)) {
6914 return otherHandle;
6915 }
6916 }
6917 return nullptr;
6918}
6919
Siarhei Vishniakoufa2a0492023-11-14 13:13:18 -08006920void InputDispatcher::setKeyRepeatConfiguration(std::chrono::nanoseconds timeout,
6921 std::chrono::nanoseconds delay) {
Nergi Rahardi730cf3c2023-04-13 12:41:17 +09006922 std::scoped_lock _l(mLock);
6923
Siarhei Vishniakoufa2a0492023-11-14 13:13:18 -08006924 mConfig.keyRepeatTimeout = timeout.count();
6925 mConfig.keyRepeatDelay = delay.count();
Nergi Rahardi730cf3c2023-04-13 12:41:17 +09006926}
6927
Garfield Tane84e6f92019-08-29 17:28:41 -07006928} // namespace android::inputdispatcher