blob: d6ff4b5834a70ed149bd97dd8966e5f894b21fd6 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
Michael Wright2b3c3302018-03-02 17:19:13 +000022#include <android-base/chrono_utils.h>
Siarhei Vishniakoud010b012023-01-18 15:00:53 -080023#include <android-base/logging.h>
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080024#include <android-base/properties.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080025#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050026#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070027#include <binder/Binder.h>
Ameer Armalycff4fa52023-10-04 23:45:11 +000028#include <com_android_input_flags.h>
Dominik Laskowski75788452021-02-09 18:51:25 -080029#include <ftl/enum.h>
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -070030#include <log/log_event_list.h>
Siarhei Vishniakou31977182022-09-30 08:51:23 -070031#if defined(__ANDROID__)
chaviw15fab6f2021-06-07 14:15:52 -050032#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou31977182022-09-30 08:51:23 -070033#endif
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080034#include <input/InputDevice.h>
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -080035#include <input/PrintTools.h>
Prabir Pradhana37bad12023-08-18 15:55:32 +000036#include <input/TraceTools.h>
tyiu1573a672023-02-21 22:38:32 +000037#include <openssl/mem.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070038#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010039#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070040#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080041
Michael Wright44753b12020-07-08 13:48:11 +010042#include <cerrno>
43#include <cinttypes>
44#include <climits>
45#include <cstddef>
46#include <ctime>
47#include <queue>
48#include <sstream>
49
Asmita Poddardd9a6cd2023-09-26 15:35:12 +000050#include "../InputDeviceMetricsSource.h"
51
Michael Wright44753b12020-07-08 13:48:11 +010052#include "Connection.h"
Arthur Hung1a1007b2022-05-11 07:15:01 +000053#include "DebugConfig.h"
Chris Yef59a2f42020-10-16 12:55:26 -070054#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010055
Michael Wrightd02c5b62014-02-10 15:10:22 -080056#define INDENT " "
57#define INDENT2 " "
58#define INDENT3 " "
59#define INDENT4 " "
60
Siarhei Vishniakou253f4642022-11-09 13:42:06 -080061using namespace android::ftl::flag_operators;
Siarhei Vishniakou23740b92023-04-21 11:30:20 -070062using android::base::Error;
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080063using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000064using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080065using android::base::StringPrintf;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -070066using android::gui::DisplayInfo;
chaviw98318de2021-05-19 16:45:23 -050067using android::gui::FocusRequest;
68using android::gui::TouchOcclusionMode;
69using android::gui::WindowInfo;
70using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080071using android::os::InputEventInjectionResult;
72using android::os::InputEventInjectionSync;
Ameer Armalycff4fa52023-10-04 23:45:11 +000073namespace input_flags = com::android::input::flags;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080074
Siarhei Vishniakou18a1d512023-12-15 13:47:33 -080075// TODO(b/312714754): remove the corresponding code, as well.
76static const bool REMOVE_APP_SWITCH_DROPS = true;
Siarhei Vishniakou17f12282023-11-02 13:40:29 -070077
Garfield Tane84e6f92019-08-29 17:28:41 -070078namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080079
Prabir Pradhancef936d2021-07-21 16:17:52 +000080namespace {
Prabir Pradhancef936d2021-07-21 16:17:52 +000081// Temporarily releases a held mutex for the lifetime of the instance.
82// Named to match std::scoped_lock
83class scoped_unlock {
84public:
85 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
86 ~scoped_unlock() { mMutex.lock(); }
87
88private:
89 std::mutex& mMutex;
90};
91
Michael Wrightd02c5b62014-02-10 15:10:22 -080092// Default input dispatching timeout if there is no focused application or paused window
93// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080094const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
95 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
96 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -080097
98// Amount of time to allow for all pending events to be processed when an app switch
99// key is on the way. This is used to preempt input dispatch and drop input events
100// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000101constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800102
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800103const std::chrono::duration STALE_EVENT_TIMEOUT = std::chrono::seconds(10) * HwTimeoutMultiplier();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104
Michael Wrightd02c5b62014-02-10 15:10:22 -0800105// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +0000106constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
107
108// Log a warning when an interception call takes longer than this to process.
109constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800110
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700111// Additional key latency in case a connection is still processing some motion events.
112// This will help with the case when a user touched a button that opens a new window,
113// and gives us the chance to dispatch the key to this new window.
114constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
115
Michael Wrightd02c5b62014-02-10 15:10:22 -0800116// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000117constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
118
Antonio Kantekea47acb2021-12-23 12:41:25 -0800119// Event log tags. See EventLogTags.logtags for reference.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000120constexpr int LOGTAG_INPUT_INTERACTION = 62000;
121constexpr int LOGTAG_INPUT_FOCUS = 62001;
Arthur Hungb3307ee2021-10-14 10:57:37 +0000122constexpr int LOGTAG_INPUT_CANCEL = 62003;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000123
Prabir Pradhan33e3baa2022-12-06 20:30:22 +0000124const ui::Transform kIdentityTransform;
125
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000126inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800127 return systemTime(SYSTEM_TIME_MONOTONIC);
128}
129
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700130inline const std::string binderToString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000131 if (binder == nullptr) {
132 return "<null>";
133 }
134 return StringPrintf("%p", binder.get());
135}
136
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000137static std::string uidString(const gui::Uid& uid) {
138 return uid.toString();
139}
140
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700141Result<void> checkKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800142 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700143 case AKEY_EVENT_ACTION_DOWN:
144 case AKEY_EVENT_ACTION_UP:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700145 return {};
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700146 default:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700147 return Error() << "Key event has invalid action code " << action;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800148 }
149}
150
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700151Result<void> validateKeyEvent(int32_t action) {
152 return checkKeyAction(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800153}
154
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700155Result<void> checkMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800156 switch (MotionEvent::getActionMasked(action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700157 case AMOTION_EVENT_ACTION_DOWN:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700158 case AMOTION_EVENT_ACTION_UP: {
159 if (pointerCount != 1) {
160 return Error() << "invalid pointer count " << pointerCount;
161 }
162 return {};
163 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700164 case AMOTION_EVENT_ACTION_MOVE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700165 case AMOTION_EVENT_ACTION_HOVER_ENTER:
166 case AMOTION_EVENT_ACTION_HOVER_MOVE:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700167 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
168 if (pointerCount < 1) {
169 return Error() << "invalid pointer count " << pointerCount;
170 }
171 return {};
172 }
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800173 case AMOTION_EVENT_ACTION_CANCEL:
174 case AMOTION_EVENT_ACTION_OUTSIDE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700175 case AMOTION_EVENT_ACTION_SCROLL:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700176 return {};
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700177 case AMOTION_EVENT_ACTION_POINTER_DOWN:
178 case AMOTION_EVENT_ACTION_POINTER_UP: {
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800179 const int32_t index = MotionEvent::getActionIndex(action);
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700180 if (index < 0) {
181 return Error() << "invalid index " << index << " for "
182 << MotionEvent::actionToString(action);
183 }
184 if (index >= pointerCount) {
185 return Error() << "invalid index " << index << " for pointerCount " << pointerCount;
186 }
187 if (pointerCount <= 1) {
188 return Error() << "invalid pointer count " << pointerCount << " for "
189 << MotionEvent::actionToString(action);
190 }
191 return {};
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700192 }
193 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700194 case AMOTION_EVENT_ACTION_BUTTON_RELEASE: {
195 if (actionButton == 0) {
196 return Error() << "action button should be nonzero for "
197 << MotionEvent::actionToString(action);
198 }
199 return {};
200 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700201 default:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700202 return Error() << "invalid action " << action;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800203 }
204}
205
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000206int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500207 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
208}
209
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700210Result<void> validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
211 const PointerProperties* pointerProperties) {
212 Result<void> actionCheck = checkMotionAction(action, actionButton, pointerCount);
213 if (!actionCheck.ok()) {
214 return actionCheck;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800215 }
216 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700217 return Error() << "Motion event has invalid pointer count " << pointerCount
218 << "; value must be between 1 and " << MAX_POINTERS << ".";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800219 }
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800220 std::bitset<MAX_POINTER_ID + 1> pointerIdBits;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800221 for (size_t i = 0; i < pointerCount; i++) {
222 int32_t id = pointerProperties[i].id;
223 if (id < 0 || id > MAX_POINTER_ID) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700224 return Error() << "Motion event has invalid pointer id " << id
225 << "; value must be between 0 and " << MAX_POINTER_ID;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800226 }
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800227 if (pointerIdBits.test(id)) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700228 return Error() << "Motion event has duplicate pointer id " << id;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800229 }
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800230 pointerIdBits.set(id);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800231 }
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700232 return {};
233}
234
235Result<void> validateInputEvent(const InputEvent& event) {
236 switch (event.getType()) {
237 case InputEventType::KEY: {
238 const KeyEvent& key = static_cast<const KeyEvent&>(event);
239 const int32_t action = key.getAction();
240 return validateKeyEvent(action);
241 }
242 case InputEventType::MOTION: {
243 const MotionEvent& motion = static_cast<const MotionEvent&>(event);
244 const int32_t action = motion.getAction();
245 const size_t pointerCount = motion.getPointerCount();
246 const PointerProperties* pointerProperties = motion.getPointerProperties();
247 const int32_t actionButton = motion.getActionButton();
248 return validateMotionEvent(action, actionButton, pointerCount, pointerProperties);
249 }
250 default: {
251 return {};
252 }
253 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800254}
255
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -0800256std::bitset<MAX_POINTER_ID + 1> getPointerIds(const std::vector<PointerProperties>& pointers) {
257 std::bitset<MAX_POINTER_ID + 1> pointerIds;
258 for (const PointerProperties& pointer : pointers) {
259 pointerIds.set(pointer.id);
260 }
261 return pointerIds;
262}
263
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000264std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800265 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000266 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800267 }
268
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000269 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800270 bool first = true;
271 Region::const_iterator cur = region.begin();
272 Region::const_iterator const tail = region.end();
273 while (cur != tail) {
274 if (first) {
275 first = false;
276 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800277 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800278 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800279 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800280 cur++;
281 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000282 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800283}
284
Prabir Pradhan8c90d782023-09-15 21:16:44 +0000285std::string dumpQueue(const std::deque<std::unique_ptr<DispatchEntry>>& queue,
286 nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500287 constexpr size_t maxEntries = 50; // max events to print
288 constexpr size_t skipBegin = maxEntries / 2;
289 const size_t skipEnd = queue.size() - maxEntries / 2;
290 // skip from maxEntries / 2 ... size() - maxEntries/2
291 // only print from 0 .. skipBegin and then from skipEnd .. size()
292
293 std::string dump;
294 for (size_t i = 0; i < queue.size(); i++) {
295 const DispatchEntry& entry = *queue[i];
296 if (i >= skipBegin && i < skipEnd) {
297 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
298 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
299 continue;
300 }
301 dump.append(INDENT4);
302 dump += entry.eventEntry->getDescription();
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +0000303 dump += StringPrintf(", seq=%" PRIu32 ", targetFlags=%s, age=%" PRId64 "ms", entry.seq,
304 entry.targetFlags.string().c_str(),
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500305 ns2ms(currentTime - entry.eventEntry->eventTime));
306 if (entry.deliveryTime != 0) {
307 // This entry was delivered, so add information on how long we've been waiting
308 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
309 }
310 dump.append("\n");
311 }
312 return dump;
313}
314
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700315/**
316 * Find the entry in std::unordered_map by key, and return it.
317 * If the entry is not found, return a default constructed entry.
318 *
319 * Useful when the entries are vectors, since an empty vector will be returned
320 * if the entry is not found.
321 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
322 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700323template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000324V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700325 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700326 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800327}
328
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000329bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700330 if (first == second) {
331 return true;
332 }
333
334 if (first == nullptr || second == nullptr) {
335 return false;
336 }
337
338 return first->getToken() == second->getToken();
339}
340
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000341bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000342 if (first == nullptr || second == nullptr) {
343 return false;
344 }
345 return first->applicationInfo.token != nullptr &&
346 first->applicationInfo.token == second->applicationInfo.token;
347}
348
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800349template <typename T>
350size_t firstMarkedBit(T set) {
351 // TODO: replace with std::countr_zero from <bit> when that's available
352 LOG_ALWAYS_FATAL_IF(set.none());
353 size_t i = 0;
354 while (!set.test(i)) {
355 i++;
356 }
357 return i;
358}
359
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800360std::unique_ptr<DispatchEntry> createDispatchEntry(
Prabir Pradhan24047542023-11-02 17:14:59 +0000361 const InputTarget& inputTarget, std::shared_ptr<const EventEntry> eventEntry,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800362 ftl::Flags<InputTarget::Flags> inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700363 if (inputTarget.useDefaultPointerTransform()) {
364 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700365 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700366 inputTarget.displayTransform,
367 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000368 }
369
370 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
371 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
372
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700373 std::vector<PointerCoords> pointerCoords;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700374 pointerCoords.resize(motionEntry.getPointerCount());
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000375
376 // Use the first pointer information to normalize all other pointers. This could be any pointer
377 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700378 // uses the transform for the normalized pointer.
379 const ui::Transform& firstPointerTransform =
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800380 inputTarget.pointerTransforms[firstMarkedBit(inputTarget.pointerIds)];
chaviw1ff3d1e2020-07-01 15:53:47 -0700381 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000382
383 // Iterate through all pointers in the event to normalize against the first.
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700384 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount(); pointerIndex++) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000385 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
386 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700387 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000388
389 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700390 // First, apply the current pointer's transform to update the coordinates into
391 // window space.
392 pointerCoords[pointerIndex].transform(currTransform);
393 // Next, apply the inverse transform of the normalized coordinates so the
394 // current coordinates are transformed into the normalized coordinate space.
395 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000396 }
397
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700398 std::unique_ptr<MotionEntry> combinedMotionEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +0000399 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.injectionState,
400 motionEntry.eventTime, motionEntry.deviceId,
401 motionEntry.source, motionEntry.displayId,
402 motionEntry.policyFlags, motionEntry.action,
403 motionEntry.actionButton, motionEntry.flags,
404 motionEntry.metaState, motionEntry.buttonState,
405 motionEntry.classification, motionEntry.edgeFlags,
406 motionEntry.xPrecision, motionEntry.yPrecision,
407 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
408 motionEntry.downTime, motionEntry.pointerProperties,
409 pointerCoords);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000410
411 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700412 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700413 firstPointerTransform, inputTarget.displayTransform,
414 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000415 return dispatchEntry;
416}
417
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000418status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
419 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700420 std::unique_ptr<InputChannel> uniqueServerChannel;
421 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
422
423 serverChannel = std::move(uniqueServerChannel);
424 return result;
425}
426
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500427template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000428bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500429 if (lhs == nullptr && rhs == nullptr) {
430 return true;
431 }
432 if (lhs == nullptr || rhs == nullptr) {
433 return false;
434 }
435 return *lhs == *rhs;
436}
437
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000438KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000439 KeyEvent event;
440 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
441 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
442 entry.repeatCount, entry.downTime, entry.eventTime);
443 return event;
444}
445
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000446bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000447 // Do not keep track of gesture monitors. They receive every event and would disproportionately
448 // affect the statistics.
449 if (connection.monitor) {
450 return false;
451 }
452 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
453 if (!connection.responsive) {
454 return false;
455 }
456 return true;
457}
458
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000459bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000460 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
461 const int32_t& inputEventId = eventEntry.id;
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000462 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
463 return false;
464 }
465 // Only track latency for events that originated from hardware
466 if (eventEntry.isSynthesized()) {
467 return false;
468 }
469 const EventEntry::Type& inputEventEntryType = eventEntry.type;
470 if (inputEventEntryType == EventEntry::Type::KEY) {
471 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
472 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
473 return false;
474 }
475 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
476 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
477 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
478 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
479 return false;
480 }
481 } else {
482 // Not a key or a motion
483 return false;
484 }
485 if (!shouldReportMetricsForConnection(connection)) {
486 return false;
487 }
488 return true;
489}
490
Prabir Pradhancef936d2021-07-21 16:17:52 +0000491/**
492 * Connection is responsive if it has no events in the waitQueue that are older than the
493 * current time.
494 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000495bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000496 const nsecs_t currentTime = now();
Prabir Pradhan8c90d782023-09-15 21:16:44 +0000497 for (const auto& dispatchEntry : connection.waitQueue) {
498 if (dispatchEntry->timeoutTime < currentTime) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000499 return false;
500 }
501 }
502 return true;
503}
504
Antonio Kantekf16f2832021-09-28 04:39:20 +0000505// Returns true if the event type passed as argument represents a user activity.
506bool isUserActivityEvent(const EventEntry& eventEntry) {
507 switch (eventEntry.type) {
Josep del Riob3981622023-04-18 15:49:45 +0000508 case EventEntry::Type::CONFIGURATION_CHANGED:
509 case EventEntry::Type::DEVICE_RESET:
510 case EventEntry::Type::DRAG:
Antonio Kantekf16f2832021-09-28 04:39:20 +0000511 case EventEntry::Type::FOCUS:
512 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Antonio Kantekf16f2832021-09-28 04:39:20 +0000513 case EventEntry::Type::SENSOR:
Josep del Riob3981622023-04-18 15:49:45 +0000514 case EventEntry::Type::TOUCH_MODE_CHANGED:
Antonio Kantekf16f2832021-09-28 04:39:20 +0000515 return false;
Antonio Kantekf16f2832021-09-28 04:39:20 +0000516 case EventEntry::Type::KEY:
517 case EventEntry::Type::MOTION:
518 return true;
519 }
520}
521
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800522// Returns true if the given window can accept pointer events at the given display location.
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000523bool windowAcceptsTouchAt(const WindowInfo& windowInfo, int32_t displayId, float x, float y,
Prabir Pradhan33e3baa2022-12-06 20:30:22 +0000524 bool isStylus, const ui::Transform& displayTransform) {
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800525 const auto inputConfig = windowInfo.inputConfig;
526 if (windowInfo.displayId != displayId ||
527 inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800528 return false;
529 }
Prabir Pradhand65552b2021-10-07 11:23:50 -0700530 const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800531 if (inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800532 return false;
533 }
Prabir Pradhan33e3baa2022-12-06 20:30:22 +0000534
535 // Window Manager works in the logical display coordinate space. When it specifies bounds for a
536 // window as (l, t, r, b), the range of x in [l, r) and y in [t, b) are considered to be inside
537 // the window. Points on the right and bottom edges should not be inside the window, so we need
538 // to be careful about performing a hit test when the display is rotated, since the "right" and
539 // "bottom" of the window will be different in the display (un-rotated) space compared to in the
540 // logical display in which WM determined the bounds. Perform the hit test in the logical
541 // display space to ensure these edges are considered correctly in all orientations.
542 const auto touchableRegion = displayTransform.transform(windowInfo.touchableRegion);
543 const auto p = displayTransform.transform(x, y);
544 if (!touchableRegion.contains(std::floor(p.x), std::floor(p.y))) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800545 return false;
546 }
547 return true;
548}
549
Prabir Pradhand65552b2021-10-07 11:23:50 -0700550bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
551 return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
Prabir Pradhane5626962022-10-27 20:30:53 +0000552 isStylusToolType(entry.pointerProperties[pointerIndex].toolType);
Prabir Pradhand65552b2021-10-07 11:23:50 -0700553}
554
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800555// Determines if the given window can be targeted as InputTarget::Flags::FOREGROUND.
Prabir Pradhan6dfbf262022-03-14 15:24:30 +0000556// Foreground events are only sent to "foreground targetable" windows, but not all gestures sent to
557// such window are necessarily targeted with the flag. For example, an event with ACTION_OUTSIDE can
558// be sent to such a window, but it is not a foreground event and doesn't use
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800559// InputTarget::Flags::FOREGROUND.
Prabir Pradhan6dfbf262022-03-14 15:24:30 +0000560bool canReceiveForegroundTouches(const WindowInfo& info) {
561 // A non-touchable window can still receive touch events (e.g. in the case of
562 // STYLUS_INTERCEPTOR), so prevent such windows from receiving foreground events for touches.
563 return !info.inputConfig.test(gui::WindowInfo::InputConfig::NOT_TOUCHABLE) && !info.isSpy();
564}
565
Prabir Pradhanaeebeb42023-06-13 19:53:03 +0000566bool isWindowOwnedBy(const sp<WindowInfoHandle>& windowHandle, gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -0700567 if (windowHandle == nullptr) {
568 return false;
569 }
570 const WindowInfo* windowInfo = windowHandle->getInfo();
571 if (pid == windowInfo->ownerPid && uid == windowInfo->ownerUid) {
572 return true;
573 }
574 return false;
575}
576
Prabir Pradhan5735a322022-04-11 17:23:34 +0000577// Checks targeted injection using the window's owner's uid.
578// Returns an empty string if an entry can be sent to the given window, or an error message if the
579// entry is a targeted injection whose uid target doesn't match the window owner.
580std::optional<std::string> verifyTargetedInjection(const sp<WindowInfoHandle>& window,
581 const EventEntry& entry) {
582 if (entry.injectionState == nullptr || !entry.injectionState->targetUid) {
583 // The event was not injected, or the injected event does not target a window.
584 return {};
585 }
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000586 const auto uid = *entry.injectionState->targetUid;
Prabir Pradhan5735a322022-04-11 17:23:34 +0000587 if (window == nullptr) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000588 return StringPrintf("No valid window target for injection into uid %s.",
589 uid.toString().c_str());
Prabir Pradhan5735a322022-04-11 17:23:34 +0000590 }
591 if (entry.injectionState->targetUid != window->getInfo()->ownerUid) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000592 return StringPrintf("Injected event targeted at uid %s would be dispatched to window '%s' "
593 "owned by uid %s.",
594 uid.toString().c_str(), window->getName().c_str(),
595 window->getInfo()->ownerUid.toString().c_str());
Prabir Pradhan5735a322022-04-11 17:23:34 +0000596 }
597 return {};
598}
599
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000600std::pair<float, float> resolveTouchedPosition(const MotionEntry& entry) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700601 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
602 // Always dispatch mouse events to cursor position.
603 if (isFromMouse) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000604 return {entry.xCursorPosition, entry.yCursorPosition};
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700605 }
606
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -0700607 const int32_t pointerIndex = MotionEvent::getActionIndex(entry.action);
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000608 return {entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X),
609 entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y)};
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700610}
611
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -0700612std::optional<nsecs_t> getDownTime(const EventEntry& eventEntry) {
613 if (eventEntry.type == EventEntry::Type::KEY) {
614 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
615 return keyEntry.downTime;
616 } else if (eventEntry.type == EventEntry::Type::MOTION) {
617 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
618 return motionEntry.downTime;
619 }
620 return std::nullopt;
621}
622
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000623/**
624 * Compare the old touch state to the new touch state, and generate the corresponding touched
625 * windows (== input targets).
626 * If a window had the hovering pointer, but now it doesn't, produce HOVER_EXIT for that window.
627 * If the pointer just entered the new window, produce HOVER_ENTER.
628 * For pointers remaining in the window, produce HOVER_MOVE.
629 */
630std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState,
631 const TouchState& newTouchState,
632 const MotionEntry& entry) {
633 std::vector<TouchedWindow> out;
634 const int32_t maskedAction = MotionEvent::getActionMasked(entry.action);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -0700635
636 if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
637 // ACTION_SCROLL events should not affect the hovering pointer dispatch
638 return {};
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000639 }
640
641 // We should consider all hovering pointers here. But for now, just use the first one
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -0800642 const PointerProperties& pointer = entry.pointerProperties[0];
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000643
644 std::set<sp<WindowInfoHandle>> oldWindows;
645 if (oldState != nullptr) {
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -0800646 oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointer.id);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000647 }
648
649 std::set<sp<WindowInfoHandle>> newWindows =
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -0800650 newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointer.id);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000651
652 // If the pointer is no longer in the new window set, send HOVER_EXIT.
653 for (const sp<WindowInfoHandle>& oldWindow : oldWindows) {
654 if (newWindows.find(oldWindow) == newWindows.end()) {
655 TouchedWindow touchedWindow;
656 touchedWindow.windowHandle = oldWindow;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000657 touchedWindow.dispatchMode = InputTarget::DispatchMode::HOVER_EXIT;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000658 out.push_back(touchedWindow);
659 }
660 }
661
662 for (const sp<WindowInfoHandle>& newWindow : newWindows) {
663 TouchedWindow touchedWindow;
664 touchedWindow.windowHandle = newWindow;
665 if (oldWindows.find(newWindow) == oldWindows.end()) {
666 // Any windows that have this pointer now, and didn't have it before, should get
667 // HOVER_ENTER
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000668 touchedWindow.dispatchMode = InputTarget::DispatchMode::HOVER_ENTER;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000669 } else {
670 // This pointer was already sent to the window. Use ACTION_HOVER_MOVE.
Siarhei Vishniakouc2eb8502023-04-11 18:33:36 -0700671 if (CC_UNLIKELY(maskedAction != AMOTION_EVENT_ACTION_HOVER_MOVE)) {
Daniel Norman7487dfa2023-08-02 16:39:45 -0700672 android::base::LogSeverity severity = android::base::LogSeverity::FATAL;
Ameer Armalycff4fa52023-10-04 23:45:11 +0000673 if (!input_flags::a11y_crash_on_inconsistent_event_stream() &&
674 entry.flags & AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT) {
Daniel Norman7487dfa2023-08-02 16:39:45 -0700675 // The Accessibility injected touch exploration event stream
676 // has known inconsistencies, so log ERROR instead of
677 // crashing the device with FATAL.
Daniel Norman7487dfa2023-08-02 16:39:45 -0700678 severity = android::base::LogSeverity::ERROR;
679 }
680 LOG(severity) << "Expected ACTION_HOVER_MOVE instead of " << entry.getDescription();
Siarhei Vishniakouc2eb8502023-04-11 18:33:36 -0700681 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000682 touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000683 }
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -0800684 touchedWindow.addHoveringPointer(entry.deviceId, pointer);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000685 if (canReceiveForegroundTouches(*newWindow->getInfo())) {
686 touchedWindow.targetFlags |= InputTarget::Flags::FOREGROUND;
687 }
688 out.push_back(touchedWindow);
689 }
690 return out;
691}
692
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -0800693template <typename T>
694std::vector<T>& operator+=(std::vector<T>& left, const std::vector<T>& right) {
695 left.insert(left.end(), right.begin(), right.end());
696 return left;
697}
698
Harry Cuttsb166c002023-05-09 13:06:05 +0000699// Filter windows in a TouchState and targets in a vector to remove untrusted windows/targets from
700// both.
701void filterUntrustedTargets(TouchState& touchState, std::vector<InputTarget>& targets) {
702 std::erase_if(touchState.windows, [&](const TouchedWindow& window) {
703 if (!window.windowHandle->getInfo()->inputConfig.test(
704 WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
705 // In addition to TouchState, erase this window from the input targets! We don't have a
706 // good way to do this today except by adding a nested loop.
707 // TODO(b/282025641): simplify this code once InputTargets are being identified
708 // separately from TouchedWindows.
709 std::erase_if(targets, [&](const InputTarget& target) {
710 return target.inputChannel->getConnectionToken() == window.windowHandle->getToken();
711 });
712 return true;
713 }
714 return false;
715 });
716}
717
Siarhei Vishniakouce1fd472023-09-18 18:38:07 -0700718/**
719 * In general, touch should be always split between windows. Some exceptions:
720 * 1. Don't split touch if all of the below is true:
721 * (a) we have an active pointer down *and*
722 * (b) a new pointer is going down that's from the same device *and*
723 * (c) the window that's receiving the current pointer does not support split touch.
724 * 2. Don't split mouse events
725 */
726bool shouldSplitTouch(const TouchState& touchState, const MotionEntry& entry) {
727 if (isFromSource(entry.source, AINPUT_SOURCE_MOUSE)) {
728 // We should never split mouse events
729 return false;
730 }
731 for (const TouchedWindow& touchedWindow : touchState.windows) {
732 if (touchedWindow.windowHandle->getInfo()->isSpy()) {
733 // Spy windows should not affect whether or not touch is split.
734 continue;
735 }
736 if (touchedWindow.windowHandle->getInfo()->supportsSplitTouch()) {
737 continue;
738 }
739 if (touchedWindow.windowHandle->getInfo()->inputConfig.test(
740 gui::WindowInfo::InputConfig::IS_WALLPAPER)) {
741 // Wallpaper window should not affect whether or not touch is split
742 continue;
743 }
744
745 if (touchedWindow.hasTouchingPointers(entry.deviceId)) {
746 return false;
747 }
748 }
749 return true;
750}
751
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000752} // namespace
753
Michael Wrightd02c5b62014-02-10 15:10:22 -0800754// --- InputDispatcher ---
755
Prabir Pradhana41d2442023-04-20 21:30:40 +0000756InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy)
Garfield Tan00f511d2019-06-12 16:55:40 -0700757 : mPolicy(policy),
758 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700759 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800760 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700761 mAppSwitchSawKeyDown(false),
Colin Cross5b799302022-10-18 21:52:41 -0700762 mAppSwitchDueTime(LLONG_MAX),
Garfield Tan00f511d2019-06-12 16:55:40 -0700763 mNextUnblockedEvent(nullptr),
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800764 mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
Garfield Tan00f511d2019-06-12 16:55:40 -0700765 mDispatchEnabled(false),
766 mDispatchFrozen(false),
767 mInputFilterEnabled(false),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100768 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000769 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800770 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000771 mLatencyAggregator(),
Antonio Kantek15beb512022-06-13 22:35:41 +0000772 mLatencyTracker(&mLatencyAggregator) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700773 mLooper = sp<Looper>::make(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800774 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800775
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700776 mWindowInfoListener = sp<DispatcherWindowListener>::make(*this);
Siarhei Vishniakou31977182022-09-30 08:51:23 -0700777#if defined(__ANDROID__)
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700778 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
Siarhei Vishniakou31977182022-09-30 08:51:23 -0700779#endif
Yi Kong9b14ac62018-07-17 13:48:38 -0700780 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800781}
782
783InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000784 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800785
Prabir Pradhancef936d2021-07-21 16:17:52 +0000786 resetKeyRepeatLocked();
787 releasePendingEventLocked();
788 drainInboundQueueLocked();
789 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800790
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000791 while (!mConnectionsByToken.empty()) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -0700792 std::shared_ptr<Connection> connection = mConnectionsByToken.begin()->second;
Harry Cutts33476232023-01-30 19:57:29 +0000793 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), /*notify=*/false);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800794 }
795}
796
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700797status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700798 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700799 return ALREADY_EXISTS;
800 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700801 mThread = std::make_unique<InputThread>(
802 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
803 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700804}
805
806status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700807 if (mThread && mThread->isCallingThread()) {
808 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700809 return INVALID_OPERATION;
810 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700811 mThread.reset();
812 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700813}
814
Michael Wrightd02c5b62014-02-10 15:10:22 -0800815void InputDispatcher::dispatchOnce() {
Colin Cross5b799302022-10-18 21:52:41 -0700816 nsecs_t nextWakeupTime = LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800817 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800818 std::scoped_lock _l(mLock);
819 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800820
821 // Run a dispatch loop if there are no pending commands.
822 // The dispatch loop might enqueue commands to run afterwards.
823 if (!haveCommandsLocked()) {
824 dispatchOnceInnerLocked(&nextWakeupTime);
825 }
826
827 // Run all pending commands if there are any.
828 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000829 if (runCommandsLockedInterruptable()) {
Colin Cross5b799302022-10-18 21:52:41 -0700830 nextWakeupTime = LLONG_MIN;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800831 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800832
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700833 // If we are still waiting for ack on some events,
834 // we might have to wake up earlier to check if an app is anr'ing.
835 const nsecs_t nextAnrCheck = processAnrsLocked();
836 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
837
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800838 // We are about to enter an infinitely long sleep, because we have no commands or
839 // pending or queued events
Colin Cross5b799302022-10-18 21:52:41 -0700840 if (nextWakeupTime == LLONG_MAX) {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800841 mDispatcherEnteredIdle.notify_all();
842 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800843 } // release lock
844
845 // Wait for callback or timeout or wake. (make sure we round up, not down)
846 nsecs_t currentTime = now();
847 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
848 mLooper->pollOnce(timeoutMillis);
849}
850
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700851/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500852 * Raise ANR if there is no focused window.
853 * Before the ANR is raised, do a final state check:
854 * 1. The currently focused application must be the same one we are waiting for.
855 * 2. Ensure we still don't have a focused window.
856 */
857void InputDispatcher::processNoFocusedWindowAnrLocked() {
858 // Check if the application that we are waiting for is still focused.
859 std::shared_ptr<InputApplicationHandle> focusedApplication =
860 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
861 if (focusedApplication == nullptr ||
862 focusedApplication->getApplicationToken() !=
863 mAwaitedFocusedApplication->getApplicationToken()) {
864 // Unexpected because we should have reset the ANR timer when focused application changed
865 ALOGE("Waited for a focused window, but focused application has already changed to %s",
866 focusedApplication->getName().c_str());
867 return; // The focused application has changed.
868 }
869
chaviw98318de2021-05-19 16:45:23 -0500870 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500871 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
872 if (focusedWindowHandle != nullptr) {
873 return; // We now have a focused window. No need for ANR.
874 }
875 onAnrLocked(mAwaitedFocusedApplication);
876}
877
878/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700879 * Check if any of the connections' wait queues have events that are too old.
880 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
881 * Return the time at which we should wake up next.
882 */
883nsecs_t InputDispatcher::processAnrsLocked() {
884 const nsecs_t currentTime = now();
Colin Cross5b799302022-10-18 21:52:41 -0700885 nsecs_t nextAnrCheck = LLONG_MAX;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700886 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
887 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
888 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500889 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700890 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500891 mNoFocusedWindowTimeoutTime = std::nullopt;
Colin Cross5b799302022-10-18 21:52:41 -0700892 return LLONG_MIN;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700893 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500894 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700895 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
896 }
897 }
898
899 // Check if any connection ANRs are due
900 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
901 if (currentTime < nextAnrCheck) { // most likely scenario
902 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
903 }
904
905 // If we reached here, we have an unresponsive connection.
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -0700906 std::shared_ptr<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700907 if (connection == nullptr) {
908 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
909 return nextAnrCheck;
910 }
911 connection->responsive = false;
912 // Stop waking up for this unresponsive connection
913 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000914 onAnrLocked(connection);
Colin Cross5b799302022-10-18 21:52:41 -0700915 return LLONG_MIN;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700916}
917
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800918std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -0700919 const std::shared_ptr<Connection>& connection) {
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800920 if (connection->monitor) {
921 return mMonitorDispatchingTimeout;
922 }
923 const sp<WindowInfoHandle> window =
924 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700925 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500926 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700927 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500928 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700929}
930
Michael Wrightd02c5b62014-02-10 15:10:22 -0800931void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
932 nsecs_t currentTime = now();
933
Jeff Browndc5992e2014-04-11 01:27:26 -0700934 // Reset the key repeat timer whenever normal dispatch is suspended while the
935 // device is in a non-interactive state. This is to ensure that we abort a key
936 // repeat if the device is just coming out of sleep.
937 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800938 resetKeyRepeatLocked();
939 }
940
941 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
942 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100943 if (DEBUG_FOCUS) {
944 ALOGD("Dispatch frozen. Waiting some more.");
945 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800946 return;
947 }
948
949 // Optimize latency of app switches.
950 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
951 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
Siarhei Vishniakou6520a582023-10-27 21:53:45 -0700952 bool isAppSwitchDue;
Siarhei Vishniakou17f12282023-11-02 13:40:29 -0700953 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -0700954 isAppSwitchDue = mAppSwitchDueTime <= currentTime;
955 if (mAppSwitchDueTime < *nextWakeupTime) {
956 *nextWakeupTime = mAppSwitchDueTime;
957 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800958 }
959
960 // Ready to start a new event.
961 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700962 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700963 if (mInboundQueue.empty()) {
Siarhei Vishniakou17f12282023-11-02 13:40:29 -0700964 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -0700965 if (isAppSwitchDue) {
966 // The inbound queue is empty so the app switch key we were waiting
967 // for will never arrive. Stop waiting for it.
968 resetPendingAppSwitchLocked(false);
969 isAppSwitchDue = false;
970 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800971 }
972
973 // Synthesize a key repeat if appropriate.
974 if (mKeyRepeatState.lastKeyEntry) {
975 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
976 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
977 } else {
978 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
979 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
980 }
981 }
982 }
983
984 // Nothing to do if there is no pending event.
985 if (!mPendingEvent) {
986 return;
987 }
988 } else {
989 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700990 mPendingEvent = mInboundQueue.front();
991 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800992 traceInboundQueueLengthLocked();
993 }
994
995 // Poke user activity for this event.
996 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700997 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800998 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800999 }
1000
1001 // Now we have an event to dispatch.
1002 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -07001003 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001004 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001005 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001006 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001007 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001008 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001009 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001010 }
1011
1012 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001013 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001014 }
1015
1016 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001017 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001018 const ConfigurationChangedEntry& typedEntry =
1019 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001020 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001021 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001022 break;
1023 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001024
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001025 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001026 const DeviceResetEntry& typedEntry =
1027 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001028 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001029 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001030 break;
1031 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001032
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001033 case EventEntry::Type::FOCUS: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001034 std::shared_ptr<const FocusEntry> typedEntry =
1035 std::static_pointer_cast<const FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001036 dispatchFocusLocked(currentTime, typedEntry);
1037 done = true;
1038 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
1039 break;
1040 }
1041
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001042 case EventEntry::Type::TOUCH_MODE_CHANGED: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001043 const auto typedEntry = std::static_pointer_cast<const TouchModeEntry>(mPendingEvent);
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001044 dispatchTouchModeChangeLocked(currentTime, typedEntry);
1045 done = true;
1046 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
1047 break;
1048 }
1049
Prabir Pradhan99987712020-11-10 18:43:05 -08001050 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1051 const auto typedEntry =
Prabir Pradhan24047542023-11-02 17:14:59 +00001052 std::static_pointer_cast<const PointerCaptureChangedEntry>(mPendingEvent);
Prabir Pradhan99987712020-11-10 18:43:05 -08001053 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
1054 done = true;
1055 break;
1056 }
1057
arthurhungb89ccb02020-12-30 16:19:01 +08001058 case EventEntry::Type::DRAG: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001059 std::shared_ptr<const DragEntry> typedEntry =
1060 std::static_pointer_cast<const DragEntry>(mPendingEvent);
arthurhungb89ccb02020-12-30 16:19:01 +08001061 dispatchDragLocked(currentTime, typedEntry);
1062 done = true;
1063 break;
1064 }
1065
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001066 case EventEntry::Type::KEY: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001067 std::shared_ptr<const KeyEntry> keyEntry =
1068 std::static_pointer_cast<const KeyEntry>(mPendingEvent);
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001069 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001070 if (isAppSwitchDue) {
1071 if (isAppSwitchKeyEvent(*keyEntry)) {
1072 resetPendingAppSwitchLocked(true);
1073 isAppSwitchDue = false;
1074 } else if (dropReason == DropReason::NOT_DROPPED) {
1075 dropReason = DropReason::APP_SWITCH;
1076 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001077 }
1078 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001079 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001080 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001081 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001082 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
1083 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001084 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001085 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001086 break;
1087 }
1088
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001089 case EventEntry::Type::MOTION: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001090 std::shared_ptr<const MotionEntry> motionEntry =
1091 std::static_pointer_cast<const MotionEntry>(mPendingEvent);
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001092 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001093 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
1094 dropReason = DropReason::APP_SWITCH;
1095 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001096 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001097 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou6b71b632023-10-27 21:34:46 -07001098 // The event is stale. However, only drop stale events if there isn't an ongoing
1099 // gesture. That would allow us to complete the processing of the current stroke.
1100 const auto touchStateIt = mTouchStatesByDisplay.find(motionEntry->displayId);
1101 if (touchStateIt != mTouchStatesByDisplay.end()) {
1102 const TouchState& touchState = touchStateIt->second;
1103 if (!touchState.hasTouchingPointers(motionEntry->deviceId) &&
1104 !touchState.hasHoveringPointers(motionEntry->deviceId)) {
1105 dropReason = DropReason::STALE;
1106 }
1107 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001108 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001109 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
1110 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001111 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001112 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001113 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001114 }
Chris Yef59a2f42020-10-16 12:55:26 -07001115
1116 case EventEntry::Type::SENSOR: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001117 std::shared_ptr<const SensorEntry> sensorEntry =
1118 std::static_pointer_cast<const SensorEntry>(mPendingEvent);
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001119 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001120 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
1121 dropReason = DropReason::APP_SWITCH;
1122 }
Chris Yef59a2f42020-10-16 12:55:26 -07001123 }
1124 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
1125 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
1126 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
1127 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
1128 dropReason = DropReason::STALE;
1129 }
1130 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
1131 done = true;
1132 break;
1133 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001134 }
1135
1136 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001137 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001138 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001139 }
Michael Wright3a981722015-06-10 15:26:13 +01001140 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001141
1142 releasePendingEventLocked();
Colin Cross5b799302022-10-18 21:52:41 -07001143 *nextWakeupTime = LLONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -08001144 }
1145}
1146
Siarhei Vishniakou289e9242022-02-15 14:50:16 -08001147bool InputDispatcher::isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
Siarhei Vishniakoua7333112023-10-27 13:33:29 -07001148 return mPolicy.isStaleEvent(currentTime, entry.eventTime);
Siarhei Vishniakou289e9242022-02-15 14:50:16 -08001149}
1150
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001151/**
1152 * Return true if the events preceding this incoming motion event should be dropped
1153 * Return false otherwise (the default behaviour)
1154 */
1155bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001156 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001157 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001158
1159 // Optimize case where the current application is unresponsive and the user
1160 // decides to touch a window in a different application.
1161 // If the application takes too long to catch up then we drop all events preceding
1162 // the touch into the other window.
1163 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07001164 const int32_t displayId = motionEntry.displayId;
1165 const auto [x, y] = resolveTouchedPosition(motionEntry);
Harry Cutts33476232023-01-30 19:57:29 +00001166 const bool isStylus = isPointerFromStylus(motionEntry, /*pointerIndex=*/0);
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07001167
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001168 sp<WindowInfoHandle> touchedWindowHandle =
1169 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001170 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001171 touchedWindowHandle->getApplicationToken() !=
1172 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001173 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001174 ALOGI("Pruning input queue because user touched a different application while waiting "
1175 "for %s",
1176 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001177 return true;
1178 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001179
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001180 // Alternatively, maybe there's a spy window that could handle this event.
1181 const std::vector<sp<WindowInfoHandle>> touchedSpies =
1182 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
1183 for (const auto& windowHandle : touchedSpies) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07001184 const std::shared_ptr<Connection> connection =
1185 getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +00001186 if (connection != nullptr && connection->responsive) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001187 // This spy window could take more input. Drop all events preceding this
1188 // event, so that the spy window can get a chance to receive the stream.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001189 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001190 "responsive spy window that may handle the event.",
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001191 mAwaitedFocusedApplication->getName().c_str());
1192 return true;
1193 }
1194 }
1195 }
1196
1197 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
1198 // yet been processed by some connections, the dispatcher will wait for these motion
1199 // events to be processed before dispatching the key event. This is because these motion events
1200 // may cause a new window to be launched, which the user might expect to receive focus.
1201 // To prevent waiting forever for such events, just send the key to the currently focused window
1202 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
1203 ALOGD("Received a new pointer down event, stop waiting for events to process and "
1204 "just send the pending key event to the focused window.");
1205 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001206 }
1207 return false;
1208}
1209
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001210bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001211 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001212 mInboundQueue.push_back(std::move(newEntry));
Prabir Pradhan24047542023-11-02 17:14:59 +00001213 const EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001214 traceInboundQueueLengthLocked();
1215
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001216 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001217 case EventEntry::Type::KEY: {
Prabir Pradhan5735a322022-04-11 17:23:34 +00001218 LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1219 "Unexpected untrusted event.");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001220 // Optimize app switch latency.
1221 // If the application takes too long to catch up then we drop all events preceding
1222 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001223 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001224
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001225 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001226 if (isAppSwitchKeyEvent(keyEntry)) {
1227 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
1228 mAppSwitchSawKeyDown = true;
1229 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
1230 if (mAppSwitchSawKeyDown) {
1231 if (DEBUG_APP_SWITCH) {
1232 ALOGD("App switch is pending!");
1233 }
1234 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
1235 mAppSwitchSawKeyDown = false;
1236 needWake = true;
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001237 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001238 }
1239 }
1240 }
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001241 // If a new up event comes in, and the pending event with same key code has been asked
1242 // to try again later because of the policy. We have to reset the intercept key wake up
1243 // time for it may have been handled in the policy and could be dropped.
1244 if (keyEntry.action == AKEY_EVENT_ACTION_UP && mPendingEvent &&
1245 mPendingEvent->type == EventEntry::Type::KEY) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001246 const KeyEntry& pendingKey = static_cast<const KeyEntry&>(*mPendingEvent);
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001247 if (pendingKey.keyCode == keyEntry.keyCode &&
1248 pendingKey.interceptKeyResult ==
Michael Wright5caf55a2022-11-24 22:31:42 +00001249 KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
1250 pendingKey.interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001251 pendingKey.interceptKeyWakeupTime = 0;
1252 needWake = true;
1253 }
1254 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001255 break;
1256 }
1257
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001258 case EventEntry::Type::MOTION: {
Prabir Pradhan5735a322022-04-11 17:23:34 +00001259 LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1260 "Unexpected untrusted event.");
Prabir Pradhan24047542023-11-02 17:14:59 +00001261 if (shouldPruneInboundQueueLocked(static_cast<const MotionEntry&>(entry))) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001262 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001263 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001264 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001265 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001266 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001267 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001268 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1269 break;
1270 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001271 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001272 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001273 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001274 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001275 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1276 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001277 // nothing to do
1278 break;
1279 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001280 }
1281
1282 return needWake;
1283}
1284
Prabir Pradhan24047542023-11-02 17:14:59 +00001285void InputDispatcher::addRecentEventLocked(std::shared_ptr<const EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001286 // Do not store sensor event in recent queue to avoid flooding the queue.
1287 if (entry->type != EventEntry::Type::SENSOR) {
1288 mRecentQueue.push_back(entry);
1289 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001290 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001291 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001292 }
1293}
1294
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001295sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, float x, float y,
1296 bool isStylus,
1297 bool ignoreDragWindow) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001298 // Traverse windows from front to back to find touched window.
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001299 const auto& windowHandles = getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05001300 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001301 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001302 continue;
1303 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001304
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001305 const WindowInfo& info = *windowHandle->getInfo();
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00001306 if (!info.isSpy() &&
1307 windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001308 return windowHandle;
1309 }
1310 }
1311 return nullptr;
1312}
1313
1314std::vector<InputTarget> InputDispatcher::findOutsideTargetsLocked(
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07001315 int32_t displayId, const sp<WindowInfoHandle>& touchedWindow, int32_t pointerId) const {
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001316 if (touchedWindow == nullptr) {
1317 return {};
1318 }
1319 // Traverse windows from front to back until we encounter the touched window.
1320 std::vector<InputTarget> outsideTargets;
1321 const auto& windowHandles = getWindowHandlesLocked(displayId);
1322 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1323 if (windowHandle == touchedWindow) {
1324 // Stop iterating once we found a touched window. Any WATCH_OUTSIDE_TOUCH window
1325 // below the touched window will not get ACTION_OUTSIDE event.
1326 return outsideTargets;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001327 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001328
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001329 const WindowInfo& info = *windowHandle->getInfo();
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08001330 if (info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07001331 std::bitset<MAX_POINTER_ID + 1> pointerIds;
1332 pointerIds.set(pointerId);
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00001333 addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::OUTSIDE,
1334 ftl::Flags<InputTarget::Flags>(), pointerIds,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07001335 /*firstDownTimeInTarget=*/std::nullopt, outsideTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001336 }
1337 }
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001338 return outsideTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001339}
1340
Prabir Pradhand65552b2021-10-07 11:23:50 -07001341std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
Prabir Pradhan82e081e2022-12-06 09:50:09 +00001342 int32_t displayId, float x, float y, bool isStylus) const {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001343 // Traverse windows from front to back and gather the touched spy windows.
1344 std::vector<sp<WindowInfoHandle>> spyWindows;
1345 const auto& windowHandles = getWindowHandlesLocked(displayId);
1346 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1347 const WindowInfo& info = *windowHandle->getInfo();
1348
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00001349 if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001350 continue;
1351 }
1352 if (!info.isSpy()) {
1353 // The first touched non-spy window was found, so return the spy windows touched so far.
1354 return spyWindows;
1355 }
1356 spyWindows.push_back(windowHandle);
1357 }
1358 return spyWindows;
1359}
1360
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001361void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001362 const char* reason;
1363 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001364 case DropReason::POLICY:
Prabir Pradhan65613802023-02-22 23:36:58 +00001365 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001366 ALOGD("Dropped event because policy consumed it.");
1367 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001368 reason = "inbound event was dropped because the policy consumed it";
1369 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001370 case DropReason::DISABLED:
1371 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001372 ALOGI("Dropped event because input dispatch is disabled.");
1373 }
1374 reason = "inbound event was dropped because input dispatch is disabled";
1375 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001376 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001377 ALOGI("Dropped event because of pending overdue app switch.");
1378 reason = "inbound event was dropped because of pending overdue app switch";
1379 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001380 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001381 ALOGI("Dropped event because the current application is not responding and the user "
1382 "has started interacting with a different application.");
1383 reason = "inbound event was dropped because the current application is not responding "
1384 "and the user has started interacting with a different application";
1385 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001386 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001387 ALOGI("Dropped event because it is stale.");
1388 reason = "inbound event was dropped because it is stale";
1389 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001390 case DropReason::NO_POINTER_CAPTURE:
1391 ALOGI("Dropped event because there is no window with Pointer Capture.");
1392 reason = "inbound event was dropped because there is no window with Pointer Capture";
1393 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001394 case DropReason::NOT_DROPPED: {
1395 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001396 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001397 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001398 }
1399
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001400 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001401 case EventEntry::Type::KEY: {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001402 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001403 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001404 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001405 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001406 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001407 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1408 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001409 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, reason);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001410 synthesizeCancelationEventsForAllConnectionsLocked(options);
1411 } else {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001412 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
1413 reason);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001414 synthesizeCancelationEventsForAllConnectionsLocked(options);
1415 }
1416 break;
1417 }
Chris Yef59a2f42020-10-16 12:55:26 -07001418 case EventEntry::Type::SENSOR: {
1419 break;
1420 }
arthurhungb89ccb02020-12-30 16:19:01 +08001421 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1422 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001423 break;
1424 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001425 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001426 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001427 case EventEntry::Type::CONFIGURATION_CHANGED:
1428 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001429 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001430 break;
1431 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001432 }
1433}
1434
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001435static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001436 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1437 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001438}
1439
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001440bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1441 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1442 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1443 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001444}
1445
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07001446bool InputDispatcher::isAppSwitchPendingLocked() const {
Colin Cross5b799302022-10-18 21:52:41 -07001447 return mAppSwitchDueTime != LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001448}
1449
1450void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
Colin Cross5b799302022-10-18 21:52:41 -07001451 mAppSwitchDueTime = LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001452
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001453 if (DEBUG_APP_SWITCH) {
1454 if (handled) {
1455 ALOGD("App switch has arrived.");
1456 } else {
1457 ALOGD("App switch was abandoned.");
1458 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001459 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001460}
1461
Michael Wrightd02c5b62014-02-10 15:10:22 -08001462bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001463 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001464}
1465
Prabir Pradhancef936d2021-07-21 16:17:52 +00001466bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001467 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001468 return false;
1469 }
1470
1471 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001472 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001473 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001474 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1475 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001476 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001477 return true;
1478}
1479
Prabir Pradhancef936d2021-07-21 16:17:52 +00001480void InputDispatcher::postCommandLocked(Command&& command) {
1481 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001482}
1483
1484void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001485 while (!mInboundQueue.empty()) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001486 std::shared_ptr<const EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001487 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001488 releaseInboundEventLocked(entry);
1489 }
1490 traceInboundQueueLengthLocked();
1491}
1492
1493void InputDispatcher::releasePendingEventLocked() {
1494 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001495 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001496 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001497 }
1498}
1499
Prabir Pradhan24047542023-11-02 17:14:59 +00001500void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<const EventEntry> entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00001501 const std::shared_ptr<InjectionState>& injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001502 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001503 if (DEBUG_DISPATCH_CYCLE) {
1504 ALOGD("Injected inbound event was dropped.");
1505 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001506 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001507 }
1508 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001509 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001510 }
1511 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001512}
1513
1514void InputDispatcher::resetKeyRepeatLocked() {
1515 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001516 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001517 }
1518}
1519
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001520std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001521 std::shared_ptr<const KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001522
Michael Wright2e732952014-09-24 13:26:59 -07001523 uint32_t policyFlags = entry->policyFlags &
1524 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001525
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001526 std::shared_ptr<KeyEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00001527 std::make_unique<KeyEntry>(mIdGenerator.nextId(), /*injectionState=*/nullptr,
1528 currentTime, entry->deviceId, entry->source,
1529 entry->displayId, policyFlags, entry->action, entry->flags,
1530 entry->keyCode, entry->scanCode, entry->metaState,
1531 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001532
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001533 newEntry->syntheticRepeat = true;
1534 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001535 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001536 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001537}
1538
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001539bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001540 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001541 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1542 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1543 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001544
1545 // Reset key repeating in case a keyboard device was added or removed or something.
1546 resetKeyRepeatLocked();
1547
1548 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001549 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1550 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00001551 mPolicy.notifyConfigurationChanged(eventTime);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001552 };
1553 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001554 return true;
1555}
1556
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001557bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1558 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001559 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1560 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1561 entry.deviceId);
1562 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001563
liushenxiang42232912021-05-21 20:24:09 +08001564 // Reset key repeating in case a keyboard device was disabled or enabled.
1565 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1566 resetKeyRepeatLocked();
1567 }
1568
Michael Wrightfb04fd52022-11-24 22:31:11 +00001569 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001570 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001571 synthesizeCancelationEventsForAllConnectionsLocked(options);
Siarhei Vishniakou0686f0c2023-05-02 11:56:15 -07001572
1573 // Remove all active pointers from this device
1574 for (auto& [_, touchState] : mTouchStatesByDisplay) {
1575 touchState.removeAllPointersForDevice(entry.deviceId);
1576 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001577 return true;
1578}
1579
Vishnu Nairad321cd2020-08-20 16:40:21 -07001580void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001581 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001582 if (mPendingEvent != nullptr) {
1583 // Move the pending event to the front of the queue. This will give the chance
1584 // for the pending event to get dispatched to the newly focused window
1585 mInboundQueue.push_front(mPendingEvent);
1586 mPendingEvent = nullptr;
1587 }
1588
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001589 std::unique_ptr<FocusEntry> focusEntry =
1590 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1591 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001592
1593 // This event should go to the front of the queue, but behind all other focus events
1594 // Find the last focus event, and insert right after it
Prabir Pradhan24047542023-11-02 17:14:59 +00001595 auto it = std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
1596 [](const std::shared_ptr<const EventEntry>& event) {
1597 return event->type == EventEntry::Type::FOCUS;
1598 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001599
1600 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001601 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001602}
1603
Prabir Pradhan24047542023-11-02 17:14:59 +00001604void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime,
1605 std::shared_ptr<const FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001606 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001607 if (channel == nullptr) {
1608 return; // Window has gone away
1609 }
1610 InputTarget target;
1611 target.inputChannel = channel;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001612 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001613 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1614 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001615 std::string reason = std::string("reason=").append(entry->reason);
1616 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001617 dispatchEventLocked(currentTime, entry, {target});
1618}
1619
Prabir Pradhan99987712020-11-10 18:43:05 -08001620void InputDispatcher::dispatchPointerCaptureChangedLocked(
Prabir Pradhan24047542023-11-02 17:14:59 +00001621 nsecs_t currentTime, const std::shared_ptr<const PointerCaptureChangedEntry>& entry,
Prabir Pradhan99987712020-11-10 18:43:05 -08001622 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001623 dropReason = DropReason::NOT_DROPPED;
1624
Prabir Pradhan99987712020-11-10 18:43:05 -08001625 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001626 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001627
1628 if (entry->pointerCaptureRequest.enable) {
1629 // Enable Pointer Capture.
1630 if (haveWindowWithPointerCapture &&
1631 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
Prabir Pradhan7092e262022-05-03 16:51:09 +00001632 // This can happen if pointer capture is disabled and re-enabled before we notify the
1633 // app of the state change, so there is no need to notify the app.
1634 ALOGI("Skipping dispatch of Pointer Capture being enabled: no state change.");
1635 return;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001636 }
1637 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001638 // This can happen if a window requests capture and immediately releases capture.
1639 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001640 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001641 return;
1642 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001643 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1644 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1645 return;
1646 }
1647
Vishnu Nairc519ff72021-01-21 08:23:08 -08001648 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001649 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1650 mWindowTokenWithPointerCapture = token;
1651 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001652 // Disable Pointer Capture.
1653 // We do not check if the sequence number matches for requests to disable Pointer Capture
1654 // for two reasons:
1655 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1656 // to disable capture with the same sequence number: one generated by
1657 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1658 // Capture being disabled in InputReader.
1659 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1660 // actual Pointer Capture state that affects events being generated by input devices is
1661 // in InputReader.
1662 if (!haveWindowWithPointerCapture) {
1663 // Pointer capture was already forcefully disabled because of focus change.
1664 dropReason = DropReason::NOT_DROPPED;
1665 return;
1666 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001667 token = mWindowTokenWithPointerCapture;
1668 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001669 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001670 setPointerCaptureLocked(false);
1671 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001672 }
1673
1674 auto channel = getInputChannelLocked(token);
1675 if (channel == nullptr) {
1676 // Window has gone away, clean up Pointer Capture state.
1677 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001678 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001679 setPointerCaptureLocked(false);
1680 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001681 return;
1682 }
1683 InputTarget target;
1684 target.inputChannel = channel;
Prabir Pradhan99987712020-11-10 18:43:05 -08001685 entry->dispatchInProgress = true;
1686 dispatchEventLocked(currentTime, entry, {target});
1687
1688 dropReason = DropReason::NOT_DROPPED;
1689}
1690
Prabir Pradhan24047542023-11-02 17:14:59 +00001691void InputDispatcher::dispatchTouchModeChangeLocked(
1692 nsecs_t currentTime, const std::shared_ptr<const TouchModeEntry>& entry) {
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001693 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Antonio Kantek15beb512022-06-13 22:35:41 +00001694 getWindowHandlesLocked(entry->displayId);
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001695 if (windowHandles.empty()) {
1696 return;
1697 }
1698 const std::vector<InputTarget> inputTargets =
1699 getInputTargetsFromWindowHandlesLocked(windowHandles);
1700 if (inputTargets.empty()) {
1701 return;
1702 }
1703 entry->dispatchInProgress = true;
1704 dispatchEventLocked(currentTime, entry, inputTargets);
1705}
1706
1707std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1708 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1709 std::vector<InputTarget> inputTargets;
1710 for (const sp<WindowInfoHandle>& handle : windowHandles) {
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001711 const sp<IBinder>& token = handle->getToken();
1712 if (token == nullptr) {
1713 continue;
1714 }
1715 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1716 if (channel == nullptr) {
1717 continue; // Window has gone away
1718 }
1719 InputTarget target;
1720 target.inputChannel = channel;
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001721 inputTargets.push_back(target);
1722 }
1723 return inputTargets;
1724}
1725
Prabir Pradhan24047542023-11-02 17:14:59 +00001726bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001727 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001728 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001729 if (!entry->dispatchInProgress) {
1730 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1731 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1732 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1733 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001734 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001735 // We have seen two identical key downs in a row which indicates that the device
1736 // driver is automatically generating key repeats itself. We take note of the
1737 // repeat here, but we disable our own next key repeat timer since it is clear that
1738 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001739 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1740 // Make sure we don't get key down from a different device. If a different
1741 // device Id has same key pressed down, the new device Id will replace the
1742 // current one to hold the key repeat with repeat count reset.
1743 // In the future when got a KEY_UP on the device id, drop it and do not
1744 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001745 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1746 resetKeyRepeatLocked();
Colin Cross5b799302022-10-18 21:52:41 -07001747 mKeyRepeatState.nextRepeatTime = LLONG_MAX; // don't generate repeats ourselves
Michael Wrightd02c5b62014-02-10 15:10:22 -08001748 } else {
1749 // Not a repeat. Save key down state in case we do see a repeat later.
1750 resetKeyRepeatLocked();
1751 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1752 }
1753 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001754 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1755 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001756 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan65613802023-02-22 23:36:58 +00001757 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001758 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1759 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001760 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001761 resetKeyRepeatLocked();
1762 }
1763
1764 if (entry->repeatCount == 1) {
1765 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1766 } else {
1767 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1768 }
1769
1770 entry->dispatchInProgress = true;
1771
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001772 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001773 }
1774
1775 // Handle case where the policy asked us to try again later last time.
Michael Wright5caf55a2022-11-24 22:31:42 +00001776 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001777 if (currentTime < entry->interceptKeyWakeupTime) {
1778 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1779 *nextWakeupTime = entry->interceptKeyWakeupTime;
1780 }
1781 return false; // wait until next wakeup
1782 }
Michael Wright5caf55a2022-11-24 22:31:42 +00001783 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001784 entry->interceptKeyWakeupTime = 0;
1785 }
1786
1787 // Give the policy a chance to intercept the key.
Michael Wright5caf55a2022-11-24 22:31:42 +00001788 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001789 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001790 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001791 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001792
1793 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1794 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1795 };
1796 postCommandLocked(std::move(command));
Josep del Riob3981622023-04-18 15:49:45 +00001797 // Poke user activity for keys not passed to user
1798 pokeUserActivityLocked(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001799 return false; // wait for the command to run
1800 } else {
Michael Wright5caf55a2022-11-24 22:31:42 +00001801 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001802 }
Michael Wright5caf55a2022-11-24 22:31:42 +00001803 } else if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001804 if (*dropReason == DropReason::NOT_DROPPED) {
1805 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001806 }
1807 }
1808
1809 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001810 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001811 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001812 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1813 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001814 mReporter->reportDroppedKey(entry->id);
Josep del Riob3981622023-04-18 15:49:45 +00001815 // Poke user activity for undispatched keys
1816 pokeUserActivityLocked(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001817 return true;
1818 }
1819
1820 // Identify targets.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001821 InputEventInjectionResult injectionResult;
1822 sp<WindowInfoHandle> focusedWindow =
1823 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime,
1824 /*byref*/ injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001825 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001826 return false;
1827 }
1828
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001829 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001830 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001831 return true;
1832 }
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001833 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
1834
1835 std::vector<InputTarget> inputTargets;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00001836 addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
1837 InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001838
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001839 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001840 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001841
1842 // Dispatch the key.
1843 dispatchEventLocked(currentTime, entry, inputTargets);
1844 return true;
1845}
1846
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001847void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001848 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1849 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1850 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1851 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1852 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1853 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1854 entry.metaState, entry.repeatCount, entry.downTime);
1855 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001856}
1857
Prabir Pradhancef936d2021-07-21 16:17:52 +00001858void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
Prabir Pradhan24047542023-11-02 17:14:59 +00001859 const std::shared_ptr<const SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001860 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001861 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1862 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1863 "source=0x%x, sensorType=%s",
1864 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001865 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001866 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001867 auto command = [this, entry]() REQUIRES(mLock) {
1868 scoped_unlock unlock(mLock);
1869
1870 if (entry->accuracyChanged) {
Prabir Pradhana41d2442023-04-20 21:30:40 +00001871 mPolicy.notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001872 }
Prabir Pradhana41d2442023-04-20 21:30:40 +00001873 mPolicy.notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1874 entry->hwTimestamp, entry->values);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001875 };
1876 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001877}
1878
1879bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001880 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1881 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001882 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001883 }
Chris Yef59a2f42020-10-16 12:55:26 -07001884 { // acquire lock
1885 std::scoped_lock _l(mLock);
1886
1887 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001888 std::shared_ptr<const EventEntry> entry = *it;
Chris Yef59a2f42020-10-16 12:55:26 -07001889 if (entry->type == EventEntry::Type::SENSOR) {
1890 it = mInboundQueue.erase(it);
1891 releaseInboundEventLocked(entry);
1892 }
1893 }
1894 }
1895 return true;
1896}
1897
Prabir Pradhan24047542023-11-02 17:14:59 +00001898bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime,
1899 std::shared_ptr<const MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001900 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001901 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001902 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001903 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001904 entry->dispatchInProgress = true;
1905
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001906 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001907 }
1908
1909 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001910 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001911 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001912 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1913 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001914 return true;
1915 }
1916
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001917 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001918
1919 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001920 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001921
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001922 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001923 if (isPointerEvent) {
1924 // Pointer event. (eg. touchscreen)
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00001925
1926 if (mDragState &&
1927 (entry->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN) {
1928 // If drag and drop ongoing and pointer down occur: pilfer drag window pointers
1929 pilferPointersLocked(mDragState->dragWindow->getToken());
1930 }
1931
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08001932 inputTargets =
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07001933 findTouchedWindowTargetsLocked(currentTime, *entry, /*byref*/ injectionResult);
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08001934 LOG_ALWAYS_FATAL_IF(injectionResult != InputEventInjectionResult::SUCCEEDED &&
1935 !inputTargets.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001936 } else {
1937 // Non touch event. (eg. trackball)
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001938 sp<WindowInfoHandle> focusedWindow =
1939 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime, injectionResult);
1940 if (injectionResult == InputEventInjectionResult::SUCCEEDED) {
1941 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00001942 addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
1943 InputTarget::Flags::FOREGROUND, getDownTime(*entry),
1944 inputTargets);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001945 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001946 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001947 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001948 return false;
1949 }
1950
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001951 setInjectionResult(*entry, injectionResult);
Prabir Pradhan5735a322022-04-11 17:23:34 +00001952 if (injectionResult == InputEventInjectionResult::TARGET_MISMATCH) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001953 return true;
1954 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001955 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001956 CancelationOptions::Mode mode(
1957 isPointerEvent ? CancelationOptions::Mode::CANCEL_POINTER_EVENTS
1958 : CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS);
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001959 CancelationOptions options(mode, "input event injection failed");
1960 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001961 return true;
1962 }
1963
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001964 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001965 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001966
1967 // Dispatch the motion.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001968 dispatchEventLocked(currentTime, entry, inputTargets);
1969 return true;
1970}
1971
chaviw98318de2021-05-19 16:45:23 -05001972void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
Arthur Hung54745652022-04-20 07:17:41 +00001973 bool isExiting, const int32_t rawX,
1974 const int32_t rawY) {
1975 const vec2 xy = windowHandle->getInfo()->transform.transform(vec2(rawX, rawY));
arthurhungb89ccb02020-12-30 16:19:01 +08001976 std::unique_ptr<DragEntry> dragEntry =
Arthur Hung54745652022-04-20 07:17:41 +00001977 std::make_unique<DragEntry>(mIdGenerator.nextId(), now(), windowHandle->getToken(),
1978 isExiting, xy.x, xy.y);
arthurhungb89ccb02020-12-30 16:19:01 +08001979
1980 enqueueInboundEventLocked(std::move(dragEntry));
1981}
1982
Prabir Pradhan24047542023-11-02 17:14:59 +00001983void InputDispatcher::dispatchDragLocked(nsecs_t currentTime,
1984 std::shared_ptr<const DragEntry> entry) {
arthurhungb89ccb02020-12-30 16:19:01 +08001985 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1986 if (channel == nullptr) {
1987 return; // Window has gone away
1988 }
1989 InputTarget target;
1990 target.inputChannel = channel;
arthurhungb89ccb02020-12-30 16:19:01 +08001991 entry->dispatchInProgress = true;
1992 dispatchEventLocked(currentTime, entry, {target});
1993}
1994
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001995void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001996 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08001997 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=%s, displayId=%" PRId32
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001998 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001999 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002000 "metaState=0x%x, buttonState=0x%x,"
2001 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08002002 prefix, entry.eventTime, entry.deviceId,
2003 inputEventSourceToString(entry.source).c_str(), entry.displayId, entry.policyFlags,
2004 MotionEvent::actionToString(entry.action).c_str(), entry.actionButton, entry.flags,
2005 entry.metaState, entry.buttonState, entry.edgeFlags, entry.xPrecision,
2006 entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002007
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002008 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
Siarhei Vishniakou09a8fe42022-07-21 17:27:03 -07002009 ALOGD(" Pointer %d: id=%d, toolType=%s, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002010 "x=%f, y=%f, pressure=%f, size=%f, "
2011 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2012 "orientation=%f",
Siarhei Vishniakou09a8fe42022-07-21 17:27:03 -07002013 i, entry.pointerProperties[i].id,
2014 ftl::enum_string(entry.pointerProperties[i].toolType).c_str(),
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002015 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2016 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2017 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2018 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2019 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2020 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2021 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2022 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2023 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2024 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002025 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002026}
2027
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002028void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
Prabir Pradhan24047542023-11-02 17:14:59 +00002029 std::shared_ptr<const EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002030 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002031 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002032 if (DEBUG_DISPATCH_CYCLE) {
2033 ALOGD("dispatchEventToCurrentInputTargets");
2034 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002035
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00002036 processInteractionsLocked(*eventEntry, inputTargets);
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002037
Michael Wrightd02c5b62014-02-10 15:10:22 -08002038 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
2039
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002040 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002041
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002042 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002043 std::shared_ptr<Connection> connection =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002044 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002045 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002046 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002047 } else {
Siarhei Vishniakou31dd1552023-10-30 18:46:10 -07002048 if (DEBUG_DROPPED_EVENTS_VERBOSE) {
2049 LOG(INFO) << "Dropping event delivery to target with channel "
2050 << inputTarget.inputChannel->getName()
2051 << " because it is no longer registered with the input dispatcher.";
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002052 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002053 }
2054 }
2055}
2056
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002057void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002058 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
2059 // If the policy decides to close the app, we will get a channel removal event via
2060 // unregisterInputChannel, and will clean up the connection that way. We are already not
2061 // sending new pointers to the connection when it blocked, but focused events will continue to
2062 // pile up.
2063 ALOGW("Canceling events for %s because it is unresponsive",
2064 connection->inputChannel->getName().c_str());
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002065 if (connection->status == Connection::Status::NORMAL) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00002066 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002067 "application not responding");
2068 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002069 }
2070}
2071
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002072void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002073 if (DEBUG_FOCUS) {
2074 ALOGD("Resetting ANR timeouts.");
2075 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002076
2077 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002078 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07002079 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002080}
2081
Tiger Huang721e26f2018-07-24 22:26:19 +08002082/**
2083 * Get the display id that the given event should go to. If this event specifies a valid display id,
2084 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
2085 * Focused display is the display that the user most recently interacted with.
2086 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002087int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08002088 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002089 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002090 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002091 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2092 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002093 break;
2094 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002095 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002096 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2097 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002098 break;
2099 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002100 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002101 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002102 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002103 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07002104 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08002105 case EventEntry::Type::SENSOR:
2106 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08002107 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002108 return ADISPLAY_ID_NONE;
2109 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002110 }
2111 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
2112}
2113
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002114bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
2115 const char* focusedWindowName) {
2116 if (mAnrTracker.empty()) {
2117 // already processed all events that we waited for
2118 mKeyIsWaitingForEventsTimeout = std::nullopt;
2119 return false;
2120 }
2121
2122 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
2123 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002124 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002125 mKeyIsWaitingForEventsTimeout = currentTime +
2126 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
2127 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002128 return true;
2129 }
2130
2131 // We still have pending events, and already started the timer
2132 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
2133 return true; // Still waiting
2134 }
2135
2136 // Waited too long, and some connection still hasn't processed all motions
2137 // Just send the key to the focused window
2138 ALOGW("Dispatching key to %s even though there are other unprocessed events",
2139 focusedWindowName);
2140 mKeyIsWaitingForEventsTimeout = std::nullopt;
2141 return false;
2142}
2143
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002144sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked(
2145 nsecs_t currentTime, const EventEntry& entry, nsecs_t* nextWakeupTime,
2146 InputEventInjectionResult& outInjectionResult) {
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002147 outInjectionResult = InputEventInjectionResult::FAILED; // Default result
Michael Wrightd02c5b62014-02-10 15:10:22 -08002148
Tiger Huang721e26f2018-07-24 22:26:19 +08002149 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05002150 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07002151 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08002152 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
2153
Michael Wrightd02c5b62014-02-10 15:10:22 -08002154 // If there is no currently focused window and no focused application
2155 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002156 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
2157 ALOGI("Dropping %s event because there is no focused window or focused application in "
2158 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08002159 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002160 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002161 }
2162
Vishnu Nair062a8672021-09-03 16:07:44 -07002163 // Drop key events if requested by input feature
2164 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002165 return nullptr;
Vishnu Nair062a8672021-09-03 16:07:44 -07002166 }
2167
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002168 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
2169 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
2170 // start interacting with another application via touch (app switch). This code can be removed
2171 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
2172 // an app is expected to have a focused window.
2173 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
2174 if (!mNoFocusedWindowTimeoutTime.has_value()) {
2175 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05002176 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
2177 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
2178 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002179 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05002180 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002181 ALOGW("Waiting because no window has focus but %s may eventually add a "
2182 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05002183 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002184 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002185 outInjectionResult = InputEventInjectionResult::PENDING;
2186 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002187 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
2188 // Already raised ANR. Drop the event
2189 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08002190 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002191 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002192 } else {
2193 // Still waiting for the focused window
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002194 outInjectionResult = InputEventInjectionResult::PENDING;
2195 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002196 }
2197 }
2198
2199 // we have a valid, non-null focused window
2200 resetNoFocusedWindowTimeoutLocked();
2201
Prabir Pradhan5735a322022-04-11 17:23:34 +00002202 // Verify targeted injection.
2203 if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) {
2204 ALOGW("Dropping injected event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002205 outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
2206 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002207 }
2208
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002209 if (focusedWindowHandle->getInfo()->inputConfig.test(
2210 WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002211 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002212 outInjectionResult = InputEventInjectionResult::PENDING;
2213 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002214 }
2215
2216 // If the event is a key event, then we must wait for all previous events to
2217 // complete before delivering it because previous events may have the
2218 // side-effect of transferring focus to a different window and we want to
2219 // ensure that the following keys are sent to the new window.
2220 //
2221 // Suppose the user touches a button in a window then immediately presses "A".
2222 // If the button causes a pop-up window to appear then we want to ensure that
2223 // the "A" key is delivered to the new pop-up window. This is because users
2224 // often anticipate pending UI changes when typing on a keyboard.
2225 // To obtain this behavior, we must serialize key events with respect to all
2226 // prior input events.
2227 if (entry.type == EventEntry::Type::KEY) {
2228 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
2229 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002230 outInjectionResult = InputEventInjectionResult::PENDING;
2231 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002232 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002233 }
2234
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002235 outInjectionResult = InputEventInjectionResult::SUCCEEDED;
2236 return focusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002237}
2238
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002239/**
2240 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
2241 * that are currently unresponsive.
2242 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002243std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
2244 const std::vector<Monitor>& monitors) const {
2245 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002246 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002247 [this](const Monitor& monitor) REQUIRES(mLock) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002248 std::shared_ptr<Connection> connection =
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002249 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002250 if (connection == nullptr) {
2251 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002252 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002253 return false;
2254 }
2255 if (!connection->responsive) {
2256 ALOGW("Unresponsive monitor %s will not get the new gesture",
2257 connection->inputChannel->getName().c_str());
2258 return false;
2259 }
2260 return true;
2261 });
2262 return responsiveMonitors;
2263}
2264
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002265std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002266 nsecs_t currentTime, const MotionEntry& entry,
Siarhei Vishniakou4fe57392022-10-25 13:44:30 -07002267 InputEventInjectionResult& outInjectionResult) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002268 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002269
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002270 std::vector<InputTarget> targets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002271 // For security reasons, we defer updating the touch state until we are sure that
2272 // event injection will be allowed.
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002273 const int32_t displayId = entry.displayId;
2274 const int32_t action = entry.action;
Siarhei Vishniakoubf880522023-05-01 11:03:22 -07002275 const int32_t maskedAction = MotionEvent::getActionMasked(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002276
2277 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002278 outInjectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002279
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002280 // Copy current touch state into tempTouchState.
2281 // This state will be used to update mTouchStatesByDisplay at the end of this function.
2282 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07002283 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002284 TouchState tempTouchState;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002285 if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
2286 oldState = &(it->second);
Prabir Pradhane680f9b2022-02-04 04:24:00 -08002287 tempTouchState = *oldState;
Jeff Brownf086ddb2014-02-11 14:28:48 -08002288 }
2289
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002290 bool isSplit = shouldSplitTouch(tempTouchState, entry);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002291
2292 const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2293 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2294 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002295 // A DOWN could be generated from POINTER_DOWN if the initial pointers did not land into any
2296 // touchable windows.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002297 const bool wasDown = oldState != nullptr && oldState->isDown(entry.deviceId);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002298 const bool isDown = (maskedAction == AMOTION_EVENT_ACTION_DOWN) ||
2299 (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN && !wasDown);
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002300 const bool newGesture = isDown || maskedAction == AMOTION_EVENT_ACTION_SCROLL ||
2301 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2302 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE;
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002303 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Siarhei Vishniakou5cee1e32022-11-29 12:35:39 -08002304
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002305 if (newGesture) {
2306 isSplit = false;
Siarhei Vishniakouf372b812023-02-14 18:06:51 -08002307 }
2308
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002309 if (isDown && tempTouchState.hasHoveringPointers(entry.deviceId)) {
2310 // Compatibility behaviour: ACTION_DOWN causes HOVER_EXIT to get generated.
2311 tempTouchState.clearHoveringPointers(entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002312 }
2313
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002314 if (isHoverAction) {
Siarhei Vishniakou7be50c92023-11-17 17:09:08 -08002315 if (wasDown) {
2316 // Started hovering, but the device is already down: reject the hover event
2317 LOG(ERROR) << "Got hover event " << entry.getDescription()
2318 << " but the device is already down " << oldState->dump();
2319 outInjectionResult = InputEventInjectionResult::FAILED;
2320 return {};
2321 }
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002322 // For hover actions, we will treat 'tempTouchState' as a new state, so let's erase
2323 // all of the existing hovering pointers and recompute.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002324 tempTouchState.clearHoveringPointers(entry.deviceId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002325 }
2326
Michael Wrightd02c5b62014-02-10 15:10:22 -08002327 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2328 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07002329 const auto [x, y] = resolveTouchedPosition(entry);
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002330 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002331 const PointerProperties& pointer = entry.pointerProperties[pointerIndex];
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002332 // Outside targets should be added upon first dispatched DOWN event. That means, this should
2333 // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down.
Prabir Pradhand65552b2021-10-07 11:23:50 -07002334 const bool isStylus = isPointerFromStylus(entry, pointerIndex);
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002335 sp<WindowInfoHandle> newTouchedWindowHandle =
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002336 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Michael Wright3dd60e22019-03-27 22:06:44 +00002337
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002338 if (isDown) {
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002339 targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointer.id);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002340 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002341 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002342 if (newTouchedWindowHandle == nullptr) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00002343 ALOGD("No new touched window at (%.1f, %.1f) in display %" PRId32, x, y, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002344 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002345 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002346 }
2347
Prabir Pradhan5735a322022-04-11 17:23:34 +00002348 // Verify targeted injection.
2349 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2350 ALOGW("Dropping injected touch event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002351 outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
Prabir Pradhan5735a322022-04-11 17:23:34 +00002352 newTouchedWindowHandle = nullptr;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002353 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002354 }
2355
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002356 // Figure out whether splitting will be allowed for this window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002357 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002358 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2359 // New window supports splitting, but we should never split mouse events.
2360 isSplit = !isFromMouse;
2361 } else if (isSplit) {
2362 // New window does not support splitting but we have already split events.
2363 // Ignore the new window.
Siarhei Vishniakou25537f82023-07-18 14:35:47 -07002364 LOG(INFO) << "Skipping " << newTouchedWindowHandle->getName()
2365 << " because it doesn't support split touch";
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002366 newTouchedWindowHandle = nullptr;
2367 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002368 } else {
2369 // No window is touched, so set split to true. This will allow the next pointer down to
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002370 // be delivered to a new window which supports split touch. Pointers from a mouse device
2371 // should never be split.
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002372 isSplit = !isFromMouse;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002373 }
2374
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002375 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002376 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002377 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002378 // Process the foreground window first so that it is the first to receive the event.
2379 newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002380 }
2381
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002382 if (newTouchedWindows.empty()) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00002383 ALOGI("Dropping event because there is no touchable window at (%.1f, %.1f) on display "
2384 "%d.",
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002385 x, y, displayId);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002386 outInjectionResult = InputEventInjectionResult::FAILED;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002387 return {};
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002388 }
2389
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002390 for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07002391 if (!canWindowReceiveMotionLocked(windowHandle, entry)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002392 continue;
2393 }
2394
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002395 if (isHoverAction) {
Siarhei Vishniakoub681c202023-05-01 11:22:33 -07002396 // The "windowHandle" is the target of this hovering pointer.
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002397 tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointer);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002398 }
2399
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002400 // Set target flags.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002401 ftl::Flags<InputTarget::Flags> targetFlags;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002402
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002403 if (canReceiveForegroundTouches(*windowHandle->getInfo())) {
2404 // There should only be one touched window that can be "foreground" for the pointer.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002405 targetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002406 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002407
2408 if (isSplit) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002409 targetFlags |= InputTarget::Flags::SPLIT;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002410 }
2411 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002412 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002413 } else if (isWindowObscuredLocked(windowHandle)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002414 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002415 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002416
2417 // Update the temporary touch state.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002418
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002419 if (!isHoverAction) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002420 const bool isDownOrPointerDown = maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2421 maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002422 tempTouchState.addOrUpdateWindow(windowHandle, InputTarget::DispatchMode::AS_IS,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002423 targetFlags, entry.deviceId, {pointer},
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002424 isDownOrPointerDown
2425 ? std::make_optional(entry.eventTime)
2426 : std::nullopt);
2427 // If this is the pointer going down and the touched window has a wallpaper
2428 // then also add the touched wallpaper windows so they are locked in for the
2429 // duration of the touch gesture. We do not collect wallpapers during HOVER_MOVE or
2430 // SCROLL because the wallpaper engine only supports touch events. We would need to
2431 // add a mechanism similar to View.onGenericMotionEvent to enable wallpapers to
2432 // handle these events.
2433 if (isDownOrPointerDown && targetFlags.test(InputTarget::Flags::FOREGROUND) &&
Arthur Hungc539dbb2022-12-08 07:45:36 +00002434 windowHandle->getInfo()->inputConfig.test(
2435 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
2436 sp<WindowInfoHandle> wallpaper = findWallpaperWindowBelow(windowHandle);
2437 if (wallpaper != nullptr) {
2438 ftl::Flags<InputTarget::Flags> wallpaperFlags =
2439 InputTarget::Flags::WINDOW_IS_OBSCURED |
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002440 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Arthur Hungc539dbb2022-12-08 07:45:36 +00002441 if (isSplit) {
2442 wallpaperFlags |= InputTarget::Flags::SPLIT;
2443 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002444 tempTouchState.addOrUpdateWindow(wallpaper,
2445 InputTarget::DispatchMode::AS_IS,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002446 wallpaperFlags, entry.deviceId, {pointer},
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002447 entry.eventTime);
Arthur Hungc539dbb2022-12-08 07:45:36 +00002448 }
2449 }
2450 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002451 }
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00002452
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002453 // If a window is already pilfering some pointers, give it this new pointer as well and
2454 // make it pilfering. This will prevent other non-spy windows from getting this pointer,
2455 // which is a specific behaviour that we want.
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002456 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002457 if (touchedWindow.hasTouchingPointer(entry.deviceId, pointer.id) &&
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002458 touchedWindow.hasPilferingPointers(entry.deviceId)) {
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002459 // This window is already pilfering some pointers, and this new pointer is also
2460 // going to it. Therefore, take over this pointer and don't give it to anyone
2461 // else.
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002462 touchedWindow.addPilferingPointer(entry.deviceId, pointer.id);
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00002463 }
2464 }
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002465
2466 // Restrict all pilfered pointers to the pilfering windows.
2467 tempTouchState.cancelPointersForNonPilferingWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002468 } else {
2469 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2470
2471 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002472 if (!tempTouchState.isDown(entry.deviceId) &&
2473 maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) {
Siarhei Vishniakou31dd1552023-10-30 18:46:10 -07002474 if (DEBUG_DROPPED_EVENTS_VERBOSE) {
2475 LOG(INFO) << "Dropping event because the pointer for device " << entry.deviceId
2476 << " is not down or we previously dropped the pointer down event in "
2477 << "display " << displayId << ": " << entry.getDescription();
2478 }
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002479 outInjectionResult = InputEventInjectionResult::FAILED;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002480 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002481 }
2482
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002483 // If the pointer is not currently hovering, then ignore the event.
2484 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2485 const int32_t pointerId = entry.pointerProperties[0].id;
2486 if (oldState == nullptr ||
2487 oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId).empty()) {
2488 LOG(INFO) << "Dropping event because the hovering pointer is not in any windows in "
2489 "display "
2490 << displayId << ": " << entry.getDescription();
2491 outInjectionResult = InputEventInjectionResult::FAILED;
2492 return {};
2493 }
2494 tempTouchState.removeHoveringPointer(entry.deviceId, pointerId);
2495 }
2496
arthurhung6d4bed92021-03-17 11:59:33 +08002497 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002498
Michael Wrightd02c5b62014-02-10 15:10:22 -08002499 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002500 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.getPointerCount() == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002501 tempTouchState.isSlippery()) {
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07002502 const auto [x, y] = resolveTouchedPosition(entry);
Harry Cutts33476232023-01-30 19:57:29 +00002503 const bool isStylus = isPointerFromStylus(entry, /*pointerIndex=*/0);
chaviw98318de2021-05-19 16:45:23 -05002504 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002505 tempTouchState.getFirstForegroundWindowHandle();
Siarhei Vishniakou0f6558d2023-04-21 12:05:13 -07002506 LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr);
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002507 sp<WindowInfoHandle> newTouchedWindowHandle =
2508 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Vishnu Nair062a8672021-09-03 16:07:44 -07002509
Prabir Pradhan5735a322022-04-11 17:23:34 +00002510 // Verify targeted injection.
2511 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2512 ALOGW("Dropping injected event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002513 outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002514 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002515 }
2516
Vishnu Nair062a8672021-09-03 16:07:44 -07002517 // Drop touch events if requested by input feature
2518 if (newTouchedWindowHandle != nullptr &&
2519 shouldDropInput(entry, newTouchedWindowHandle)) {
2520 newTouchedWindowHandle = nullptr;
2521 }
2522
Siarhei Vishniakouafa08cc2023-05-08 22:35:50 -07002523 if (newTouchedWindowHandle != nullptr &&
2524 !haveSameToken(oldTouchedWindowHandle, newTouchedWindowHandle)) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002525 ALOGI("Touch is slipping out of window %s into window %s in display %" PRId32,
Siarhei Vishniakou0f6558d2023-04-21 12:05:13 -07002526 oldTouchedWindowHandle->getName().c_str(),
2527 newTouchedWindowHandle->getName().c_str(), displayId);
2528
Michael Wrightd02c5b62014-02-10 15:10:22 -08002529 // Make a slippery exit from the old window.
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08002530 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002531 const PointerProperties& pointer = entry.pointerProperties[0];
2532 pointerIds.set(pointer.id);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002533
2534 const TouchedWindow& touchedWindow =
2535 tempTouchState.getTouchedWindow(oldTouchedWindowHandle);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002536 addPointerWindowTargetLocked(oldTouchedWindowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002537 InputTarget::DispatchMode::SLIPPERY_EXIT,
2538 ftl::Flags<InputTarget::Flags>(), pointerIds,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002539 touchedWindow.getDownTimeInTarget(entry.deviceId),
2540 targets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002541
2542 // Make a slippery entrance into the new window.
2543 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002544 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002545 }
2546
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002547 ftl::Flags<InputTarget::Flags> targetFlags;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002548 if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002549 targetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002550 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002551 if (isSplit) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002552 targetFlags |= InputTarget::Flags::SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002553 }
2554 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002555 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002556 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002557 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002558 }
2559
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002560 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle,
2561 InputTarget::DispatchMode::SLIPPERY_ENTER,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002562 targetFlags, entry.deviceId, {pointer},
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002563 entry.eventTime);
Arthur Hungc539dbb2022-12-08 07:45:36 +00002564
2565 // Check if the wallpaper window should deliver the corresponding event.
2566 slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002567 tempTouchState, entry.deviceId, pointer, targets);
2568 tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointer.id,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002569 oldTouchedWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002570 }
2571 }
Arthur Hung96483742022-11-15 03:30:48 +00002572
2573 // Update the pointerIds for non-splittable when it received pointer down.
2574 if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2575 // If no split, we suppose all touched windows should receive pointer down.
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002576 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002577 std::vector<PointerProperties> touchingPointers{entry.pointerProperties[pointerIndex]};
2578 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
Arthur Hung96483742022-11-15 03:30:48 +00002579 // Ignore drag window for it should just track one pointer.
2580 if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
2581 continue;
2582 }
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002583 touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers);
Arthur Hung96483742022-11-15 03:30:48 +00002584 }
2585 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002586 }
2587
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002588 // Update dispatching for hover enter and exit.
Sam Dubeyf886dec2023-01-27 13:28:19 +00002589 {
2590 std::vector<TouchedWindow> hoveringWindows =
2591 getHoveringWindowsLocked(oldState, tempTouchState, entry);
2592 for (const TouchedWindow& touchedWindow : hoveringWindows) {
Siarhei Vishniakoud5876ba2023-05-15 17:58:34 -07002593 std::optional<InputTarget> target =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002594 createInputTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
2595 touchedWindow.targetFlags,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002596 touchedWindow.getDownTimeInTarget(entry.deviceId));
Siarhei Vishniakoud5876ba2023-05-15 17:58:34 -07002597 if (!target) {
2598 continue;
2599 }
2600 // Hardcode to single hovering pointer for now.
2601 std::bitset<MAX_POINTER_ID + 1> pointerIds;
2602 pointerIds.set(entry.pointerProperties[0].id);
2603 target->addPointers(pointerIds, touchedWindow.windowHandle->getInfo()->transform);
2604 targets.push_back(*target);
Sam Dubeyf886dec2023-01-27 13:28:19 +00002605 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002606 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002607
Prabir Pradhan5735a322022-04-11 17:23:34 +00002608 // Ensure that all touched windows are valid for injection.
2609 if (entry.injectionState != nullptr) {
2610 std::string errs;
2611 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Prabir Pradhan5735a322022-04-11 17:23:34 +00002612 const auto err = verifyTargetedInjection(touchedWindow.windowHandle, entry);
2613 if (err) errs += "\n - " + *err;
2614 }
2615 if (!errs.empty()) {
2616 ALOGW("Dropping targeted injection: At least one touched window is not owned by uid "
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00002617 "%s:%s",
2618 entry.injectionState->targetUid->toString().c_str(), errs.c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002619 outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002620 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002621 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002622 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002623
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002624 // Check whether windows listening for outside touches are owned by the same UID. If the owner
2625 // has a different UID, then we will not reveal coordinate information to this window.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002626 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002627 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002628 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002629 if (foregroundWindowHandle) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00002630 const auto foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002631 for (InputTarget& target : targets) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002632 if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002633 sp<WindowInfoHandle> targetWindow =
2634 getWindowHandleLocked(target.inputChannel->getConnectionToken());
2635 if (targetWindow->getInfo()->ownerUid != foregroundWindowUid) {
2636 target.flags |= InputTarget::Flags::ZERO_COORDS;
Michael Wright3dd60e22019-03-27 22:06:44 +00002637 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002638 }
2639 }
2640 }
2641 }
2642
Harry Cuttsb166c002023-05-09 13:06:05 +00002643 // If this is a touchpad navigation gesture, it needs to only be sent to trusted targets, as we
2644 // only want the system UI to handle these gestures.
2645 const bool isTouchpadNavGesture = isFromSource(entry.source, AINPUT_SOURCE_MOUSE) &&
2646 entry.classification == MotionClassification::MULTI_FINGER_SWIPE;
2647 if (isTouchpadNavGesture) {
2648 filterUntrustedTargets(/* byref */ tempTouchState, /* byref */ targets);
2649 }
2650
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002651 // Output targets from the touch state.
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002652 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002653 std::vector<PointerProperties> touchingPointers =
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002654 touchedWindow.getTouchingPointers(entry.deviceId);
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002655 if (touchingPointers.empty()) {
Siarhei Vishniakoue0431e42023-01-28 17:01:39 -08002656 continue;
2657 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002658 addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002659 touchedWindow.targetFlags, getPointerIds(touchingPointers),
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002660 touchedWindow.getDownTimeInTarget(entry.deviceId), targets);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002661 }
Sam Dubey39d37cf2022-12-07 18:05:35 +00002662
Siarhei Vishniakou580fb3a2023-05-05 15:02:20 -07002663 // During targeted injection, only allow owned targets to receive events
2664 std::erase_if(targets, [&](const InputTarget& target) {
2665 LOG_ALWAYS_FATAL_IF(target.windowHandle == nullptr);
2666 const auto err = verifyTargetedInjection(target.windowHandle, entry);
2667 if (err) {
2668 LOG(WARNING) << "Dropping injected event from " << target.windowHandle->getName()
2669 << ": " << (*err);
2670 return true;
2671 }
2672 return false;
2673 });
2674
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002675 if (targets.empty()) {
2676 LOG(INFO) << "Dropping event because no targets were found: " << entry.getDescription();
2677 outInjectionResult = InputEventInjectionResult::FAILED;
2678 return {};
2679 }
2680
2681 // If we only have windows getting ACTION_OUTSIDE, then drop the event, because there is no
2682 // window that is actually receiving the entire gesture.
2683 if (std::all_of(targets.begin(), targets.end(), [](const InputTarget& target) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002684 return target.dispatchMode == InputTarget::DispatchMode::OUTSIDE;
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002685 })) {
2686 LOG(INFO) << "Dropping event because all windows would just receive ACTION_OUTSIDE: "
2687 << entry.getDescription();
2688 outInjectionResult = InputEventInjectionResult::FAILED;
2689 return {};
2690 }
2691
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002692 outInjectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002693
Prabir Pradhan502a7252023-12-01 16:11:24 +00002694 // Now that we have generated all of the input targets for this event, reset the dispatch
2695 // mode for all touched window to AS_IS.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002696 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
Prabir Pradhan502a7252023-12-01 16:11:24 +00002697 touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002698 }
2699
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002700 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou7be50c92023-11-17 17:09:08 -08002701 if (maskedAction == AMOTION_EVENT_ACTION_UP) {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002702 // Pointer went up.
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002703 tempTouchState.removeTouchingPointer(entry.deviceId, entry.pointerProperties[0].id);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002704 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002705 // All pointers up or canceled.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002706 tempTouchState.removeAllPointersForDevice(entry.deviceId);
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002707 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2708 // One pointer went up.
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002709 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
2710 const uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
2711 tempTouchState.removeTouchingPointer(entry.deviceId, pointerId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002712 }
2713
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002714 // Save changes unless the action was scroll in which case the temporary touch
2715 // state was only valid for this one action.
2716 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07002717 if (displayId >= 0) {
Siarhei Vishniakouf372b812023-02-14 18:06:51 -08002718 tempTouchState.clearWindowsWithoutPointers();
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002719 mTouchStatesByDisplay[displayId] = tempTouchState;
2720 } else {
2721 mTouchStatesByDisplay.erase(displayId);
2722 }
2723 }
2724
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08002725 if (tempTouchState.windows.empty()) {
2726 mTouchStatesByDisplay.erase(displayId);
2727 }
2728
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002729 return targets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002730}
2731
arthurhung6d4bed92021-03-17 11:59:33 +08002732void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07002733 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2734 // have an explicit reason to support it.
2735 constexpr bool isStylus = false;
2736
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002737 sp<WindowInfoHandle> dropWindow =
Harry Cutts33476232023-01-30 19:57:29 +00002738 findTouchedWindowAtLocked(displayId, x, y, isStylus, /*ignoreDragWindow=*/true);
arthurhung6d4bed92021-03-17 11:59:33 +08002739 if (dropWindow) {
2740 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002741 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002742 } else {
Arthur Hung54745652022-04-20 07:17:41 +00002743 ALOGW("No window found when drop.");
Prabir Pradhancef936d2021-07-21 16:17:52 +00002744 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002745 }
2746 mDragState.reset();
2747}
2748
2749void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
Arthur Hung3915c1f2022-05-31 07:17:17 +00002750 if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId) {
arthurhungb89ccb02020-12-30 16:19:01 +08002751 return;
2752 }
2753
arthurhung6d4bed92021-03-17 11:59:33 +08002754 if (!mDragState->isStartDrag) {
2755 mDragState->isStartDrag = true;
2756 mDragState->isStylusButtonDownAtStart =
2757 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2758 }
2759
Arthur Hung54745652022-04-20 07:17:41 +00002760 // Find the pointer index by id.
2761 int32_t pointerIndex = 0;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002762 for (; static_cast<uint32_t>(pointerIndex) < entry.getPointerCount(); pointerIndex++) {
Arthur Hung54745652022-04-20 07:17:41 +00002763 const PointerProperties& pointerProperties = entry.pointerProperties[pointerIndex];
2764 if (pointerProperties.id == mDragState->pointerId) {
2765 break;
arthurhung6d4bed92021-03-17 11:59:33 +08002766 }
Arthur Hung54745652022-04-20 07:17:41 +00002767 }
arthurhung6d4bed92021-03-17 11:59:33 +08002768
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002769 if (uint32_t(pointerIndex) == entry.getPointerCount()) {
Arthur Hung54745652022-04-20 07:17:41 +00002770 LOG_ALWAYS_FATAL("Should find a valid pointer index by id %d", mDragState->pointerId);
Arthur Hung54745652022-04-20 07:17:41 +00002771 }
2772
2773 const int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2774 const int32_t x = entry.pointerCoords[pointerIndex].getX();
2775 const int32_t y = entry.pointerCoords[pointerIndex].getY();
2776
2777 switch (maskedAction) {
2778 case AMOTION_EVENT_ACTION_MOVE: {
2779 // Handle the special case : stylus button no longer pressed.
2780 bool isStylusButtonDown =
2781 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2782 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2783 finishDragAndDrop(entry.displayId, x, y);
2784 return;
2785 }
2786
2787 // Prevent stylus interceptor windows from affecting drag and drop behavior for now,
2788 // until we have an explicit reason to support it.
2789 constexpr bool isStylus = false;
2790
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002791 sp<WindowInfoHandle> hoverWindowHandle =
2792 findTouchedWindowAtLocked(entry.displayId, x, y, isStylus,
2793 /*ignoreDragWindow=*/true);
Arthur Hung54745652022-04-20 07:17:41 +00002794 // enqueue drag exit if needed.
2795 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2796 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2797 if (mDragState->dragHoverWindowHandle != nullptr) {
Harry Cutts33476232023-01-30 19:57:29 +00002798 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, /*isExiting=*/true, x,
Arthur Hung54745652022-04-20 07:17:41 +00002799 y);
2800 }
2801 mDragState->dragHoverWindowHandle = hoverWindowHandle;
2802 }
2803 // enqueue drag location if needed.
2804 if (hoverWindowHandle != nullptr) {
Harry Cutts33476232023-01-30 19:57:29 +00002805 enqueueDragEventLocked(hoverWindowHandle, /*isExiting=*/false, x, y);
Arthur Hung54745652022-04-20 07:17:41 +00002806 }
2807 break;
2808 }
2809
2810 case AMOTION_EVENT_ACTION_POINTER_UP:
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002811 if (MotionEvent::getActionIndex(entry.action) != pointerIndex) {
Arthur Hung54745652022-04-20 07:17:41 +00002812 break;
2813 }
2814 // The drag pointer is up.
2815 [[fallthrough]];
2816 case AMOTION_EVENT_ACTION_UP:
2817 finishDragAndDrop(entry.displayId, x, y);
2818 break;
2819 case AMOTION_EVENT_ACTION_CANCEL: {
2820 ALOGD("Receiving cancel when drag and drop.");
2821 sendDropWindowCommandLocked(nullptr, 0, 0);
2822 mDragState.reset();
2823 break;
2824 }
arthurhungb89ccb02020-12-30 16:19:01 +08002825 }
2826}
2827
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002828std::optional<InputTarget> InputDispatcher::createInputTargetLocked(
2829 const sp<android::gui::WindowInfoHandle>& windowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002830 InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002831 std::optional<nsecs_t> firstDownTimeInTarget) const {
2832 std::shared_ptr<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
2833 if (inputChannel == nullptr) {
2834 ALOGW("Not creating InputTarget for %s, no input channel", windowHandle->getName().c_str());
2835 return {};
2836 }
2837 InputTarget inputTarget;
2838 inputTarget.inputChannel = inputChannel;
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00002839 inputTarget.windowHandle = windowHandle;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002840 inputTarget.dispatchMode = dispatchMode;
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002841 inputTarget.flags = targetFlags;
2842 inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor;
2843 inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
2844 const auto& displayInfoIt = mDisplayInfos.find(windowHandle->getInfo()->displayId);
2845 if (displayInfoIt != mDisplayInfos.end()) {
2846 inputTarget.displayTransform = displayInfoIt->second.transform;
2847 } else {
Siarhei Vishniakou580fb3a2023-05-05 15:02:20 -07002848 // DisplayInfo not found for this window on display windowHandle->getInfo()->displayId.
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002849 // TODO(b/198444055): Make this an error message after 'setInputWindows' API is removed.
2850 }
2851 return inputTarget;
2852}
2853
chaviw98318de2021-05-19 16:45:23 -05002854void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002855 InputTarget::DispatchMode dispatchMode,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002856 ftl::Flags<InputTarget::Flags> targetFlags,
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002857 std::optional<nsecs_t> firstDownTimeInTarget,
Siarhei Vishniakouf75cddb2022-10-25 10:42:16 -07002858 std::vector<InputTarget>& inputTargets) const {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002859 std::vector<InputTarget>::iterator it =
2860 std::find_if(inputTargets.begin(), inputTargets.end(),
2861 [&windowHandle](const InputTarget& inputTarget) {
2862 return inputTarget.inputChannel->getConnectionToken() ==
2863 windowHandle->getToken();
2864 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002865
chaviw98318de2021-05-19 16:45:23 -05002866 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002867
2868 if (it == inputTargets.end()) {
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002869 std::optional<InputTarget> target =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002870 createInputTargetLocked(windowHandle, dispatchMode, targetFlags,
2871 firstDownTimeInTarget);
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002872 if (!target) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002873 return;
2874 }
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002875 inputTargets.push_back(*target);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002876 it = inputTargets.end() - 1;
2877 }
2878
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002879 if (it->flags != targetFlags) {
2880 LOG(ERROR) << "Flags don't match! targetFlags=" << targetFlags.string() << ", it=" << *it;
2881 }
2882 if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
2883 LOG(ERROR) << "Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
2884 << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
2885 }
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002886}
2887
2888void InputDispatcher::addPointerWindowTargetLocked(
2889 const sp<android::gui::WindowInfoHandle>& windowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002890 InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
2891 std::bitset<MAX_POINTER_ID + 1> pointerIds, std::optional<nsecs_t> firstDownTimeInTarget,
2892 std::vector<InputTarget>& inputTargets) const REQUIRES(mLock) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002893 if (pointerIds.none()) {
2894 for (const auto& target : inputTargets) {
2895 LOG(INFO) << "Target: " << target;
2896 }
2897 LOG(FATAL) << "No pointers specified for " << windowHandle->getName();
2898 return;
2899 }
2900 std::vector<InputTarget>::iterator it =
2901 std::find_if(inputTargets.begin(), inputTargets.end(),
2902 [&windowHandle](const InputTarget& inputTarget) {
2903 return inputTarget.inputChannel->getConnectionToken() ==
2904 windowHandle->getToken();
2905 });
2906
2907 // This is a hack, because the actual entry could potentially be an ACTION_DOWN event that
2908 // causes a HOVER_EXIT to be generated. That means that the same entry of ACTION_DOWN would
2909 // have DISPATCH_AS_HOVER_EXIT and DISPATCH_AS_IS. And therefore, we have to create separate
2910 // input targets for hovering pointers and for touching pointers.
2911 // If we picked an existing input target above, but it's for HOVER_EXIT - let's use a new
2912 // target instead.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002913 if (it != inputTargets.end() && it->dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002914 // Force the code below to create a new input target
2915 it = inputTargets.end();
2916 }
2917
2918 const WindowInfo* windowInfo = windowHandle->getInfo();
2919
2920 if (it == inputTargets.end()) {
2921 std::optional<InputTarget> target =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002922 createInputTargetLocked(windowHandle, dispatchMode, targetFlags,
2923 firstDownTimeInTarget);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002924 if (!target) {
2925 return;
2926 }
2927 inputTargets.push_back(*target);
2928 it = inputTargets.end() - 1;
2929 }
2930
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002931 if (it->dispatchMode != dispatchMode) {
2932 LOG(ERROR) << __func__ << ": DispatchMode doesn't match! ignoring new mode="
2933 << ftl::enum_string(dispatchMode) << ", it=" << *it;
2934 }
Siarhei Vishniakou4bd0b7c2023-10-27 00:51:14 -07002935 if (it->flags != targetFlags) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002936 LOG(ERROR) << __func__ << ": Flags don't match! new targetFlags=" << targetFlags.string()
2937 << ", it=" << *it;
Siarhei Vishniakou4bd0b7c2023-10-27 00:51:14 -07002938 }
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002939 if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002940 LOG(ERROR) << __func__ << ": Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002941 << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
2942 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002943
chaviw1ff3d1e2020-07-01 15:53:47 -07002944 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002945}
2946
Michael Wright3dd60e22019-03-27 22:06:44 +00002947void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002948 int32_t displayId) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002949 auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
2950 if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
Michael Wright3dd60e22019-03-27 22:06:44 +00002951
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002952 for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
2953 InputTarget target;
2954 target.inputChannel = monitor.inputChannel;
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002955 // target.firstDownTimeInTarget is not set for global monitors. It is only required in split
2956 // touch and global monitoring works as intended even without setting firstDownTimeInTarget
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002957 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
2958 target.displayTransform = it->second.transform;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002959 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002960 target.setDefaultPointerTransform(target.displayTransform);
2961 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002962 }
2963}
2964
Robert Carrc9bf1d32020-04-13 17:21:08 -07002965/**
2966 * Indicate whether one window handle should be considered as obscuring
2967 * another window handle. We only check a few preconditions. Actually
2968 * checking the bounds is left to the caller.
2969 */
chaviw98318de2021-05-19 16:45:23 -05002970static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2971 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002972 // Compare by token so cloned layers aren't counted
2973 if (haveSameToken(windowHandle, otherHandle)) {
2974 return false;
2975 }
2976 auto info = windowHandle->getInfo();
2977 auto otherInfo = otherHandle->getInfo();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002978 if (otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002979 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002980 } else if (otherInfo->alpha == 0 &&
2981 otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002982 // Those act as if they were invisible, so we don't need to flag them.
2983 // We do want to potentially flag touchable windows even if they have 0
2984 // opacity, since they can consume touches and alter the effects of the
2985 // user interaction (eg. apps that rely on
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002986 // Flags::WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002987 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2988 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002989 } else if (info->ownerUid == otherInfo->ownerUid) {
2990 // If ownerUid is the same we don't generate occlusion events as there
2991 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002992 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002993 } else if (otherInfo->inputConfig.test(gui::WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002994 return false;
2995 } else if (otherInfo->displayId != info->displayId) {
2996 return false;
2997 }
2998 return true;
2999}
3000
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003001/**
3002 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
3003 * untrusted, one should check:
3004 *
3005 * 1. If result.hasBlockingOcclusion is true.
3006 * If it's, it means the touch should be blocked due to a window with occlusion mode of
3007 * BLOCK_UNTRUSTED.
3008 *
3009 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
3010 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
3011 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
3012 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
3013 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
3014 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
3015 *
3016 * If neither of those is true, then it means the touch can be allowed.
3017 */
3018InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05003019 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
3020 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003021 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05003022 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003023 TouchOcclusionInfo info;
3024 info.hasBlockingOcclusion = false;
3025 info.obscuringOpacity = 0;
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003026 info.obscuringUid = gui::Uid::INVALID;
3027 std::map<gui::Uid, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05003028 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003029 if (windowHandle == otherHandle) {
3030 break; // All future windows are below us. Exit early.
3031 }
chaviw98318de2021-05-19 16:45:23 -05003032 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00003033 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
3034 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003035 if (DEBUG_TOUCH_OCCLUSION) {
3036 info.debugInfo.push_back(
Harry Cutts101ee9b2023-07-06 18:04:14 +00003037 dumpWindowForTouchOcclusion(otherInfo, /*isTouchedWindow=*/false));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003038 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003039 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
3040 // we perform the checks below to see if the touch can be propagated or not based on the
3041 // window's touch occlusion mode
3042 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
3043 info.hasBlockingOcclusion = true;
3044 info.obscuringUid = otherInfo->ownerUid;
3045 info.obscuringPackage = otherInfo->packageName;
3046 break;
3047 }
3048 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003049 const auto uid = otherInfo->ownerUid;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003050 float opacity =
3051 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
3052 // Given windows A and B:
3053 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
3054 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
3055 opacityByUid[uid] = opacity;
3056 if (opacity > info.obscuringOpacity) {
3057 info.obscuringOpacity = opacity;
3058 info.obscuringUid = uid;
3059 info.obscuringPackage = otherInfo->packageName;
3060 }
3061 }
3062 }
3063 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003064 if (DEBUG_TOUCH_OCCLUSION) {
Harry Cutts101ee9b2023-07-06 18:04:14 +00003065 info.debugInfo.push_back(dumpWindowForTouchOcclusion(windowInfo, /*isTouchedWindow=*/true));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003066 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003067 return info;
3068}
3069
chaviw98318de2021-05-19 16:45:23 -05003070std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003071 bool isTouchedWindow) const {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003072 return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
Prabir Pradhan51e7db02022-02-07 06:02:57 -08003073 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
3074 "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
3075 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08003076 isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003077 info->ownerUid.toString().c_str(), info->id,
Chavi Weingarten7f019192023-08-08 20:39:01 +00003078 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frame.left,
3079 info->frame.top, info->frame.right, info->frame.bottom,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003080 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
3081 info->inputConfig.string().c_str(), toString(info->token != nullptr),
3082 info->applicationInfo.name.c_str(),
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07003083 binderToString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003084}
3085
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003086bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
3087 if (occlusionInfo.hasBlockingOcclusion) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003088 ALOGW("Untrusted touch due to occlusion by %s/%s", occlusionInfo.obscuringPackage.c_str(),
3089 occlusionInfo.obscuringUid.toString().c_str());
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003090 return false;
3091 }
3092 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003093 ALOGW("Untrusted touch due to occlusion by %s/%s (obscuring opacity = "
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003094 "%.2f, maximum allowed = %.2f)",
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003095 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid.toString().c_str(),
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003096 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
3097 return false;
3098 }
3099 return true;
3100}
3101
chaviw98318de2021-05-19 16:45:23 -05003102bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003103 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003104 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05003105 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3106 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07003107 if (windowHandle == otherHandle) {
3108 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08003109 }
chaviw98318de2021-05-19 16:45:23 -05003110 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07003111 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08003112 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003113 return true;
3114 }
3115 }
3116 return false;
3117}
3118
chaviw98318de2021-05-19 16:45:23 -05003119bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003120 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05003121 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3122 const WindowInfo* windowInfo = windowHandle->getInfo();
3123 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07003124 if (windowHandle == otherHandle) {
3125 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003126 }
chaviw98318de2021-05-19 16:45:23 -05003127 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07003128 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08003129 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003130 return true;
3131 }
3132 }
3133 return false;
3134}
3135
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003136std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05003137 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003138 if (applicationHandle != nullptr) {
3139 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07003140 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003141 } else {
3142 return applicationHandle->getName();
3143 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003144 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07003145 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003146 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003147 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003148 }
3149}
3150
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003151void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00003152 if (!isUserActivityEvent(eventEntry)) {
3153 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003154 return;
3155 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003156 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05003157 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Josep del Riob3981622023-04-18 15:49:45 +00003158 const WindowInfo* windowDisablingUserActivityInfo = nullptr;
Tiger Huang721e26f2018-07-24 22:26:19 +08003159 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003160 const WindowInfo* info = focusedWindowHandle->getInfo();
Prabir Pradhan51e7db02022-02-07 06:02:57 -08003161 if (info->inputConfig.test(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY)) {
Josep del Riob3981622023-04-18 15:49:45 +00003162 windowDisablingUserActivityInfo = info;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003163 }
3164 }
3165
3166 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003167 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003168 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003169 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3170 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003171 return;
3172 }
Josep del Riob3981622023-04-18 15:49:45 +00003173 if (windowDisablingUserActivityInfo != nullptr) {
3174 if (DEBUG_DISPATCH_CYCLE) {
3175 ALOGD("Not poking user activity: disabled by window '%s'.",
3176 windowDisablingUserActivityInfo->name.c_str());
3177 }
3178 return;
3179 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003180 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003181 eventType = USER_ACTIVITY_EVENT_TOUCH;
3182 }
3183 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003184 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003185 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003186 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3187 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003188 return;
3189 }
Josep del Riob3981622023-04-18 15:49:45 +00003190 // If the key code is unknown, we don't consider it user activity
3191 if (keyEntry.keyCode == AKEYCODE_UNKNOWN) {
3192 return;
3193 }
3194 // Don't inhibit events that were intercepted or are not passed to
3195 // the apps, like system shortcuts
3196 if (windowDisablingUserActivityInfo != nullptr &&
3197 keyEntry.interceptKeyResult != KeyEntry::InterceptKeyResult::SKIP &&
3198 keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER) {
3199 if (DEBUG_DISPATCH_CYCLE) {
3200 ALOGD("Not poking user activity: disabled by window '%s'.",
3201 windowDisablingUserActivityInfo->name.c_str());
3202 }
3203 return;
3204 }
3205
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003206 eventType = USER_ACTIVITY_EVENT_BUTTON;
3207 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003208 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00003209 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003210 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08003211 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003212 break;
3213 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003214 }
3215
Prabir Pradhancef936d2021-07-21 16:17:52 +00003216 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
3217 REQUIRES(mLock) {
3218 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003219 mPolicy.pokeUserActivity(eventTime, eventType, displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00003220 };
3221 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003222}
3223
3224void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003225 const std::shared_ptr<Connection>& connection,
Prabir Pradhan24047542023-11-02 17:14:59 +00003226 std::shared_ptr<const EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003227 const InputTarget& inputTarget) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003228 ATRACE_NAME_IF(ATRACE_ENABLED(),
3229 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
3230 connection->getInputChannelName().c_str(), eventEntry->id));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003231 if (DEBUG_DISPATCH_CYCLE) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003232 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=%s, "
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08003233 "globalScaleFactor=%f, pointerIds=%s %s",
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003234 connection->getInputChannelName().c_str(), inputTarget.flags.string().c_str(),
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08003235 inputTarget.globalScaleFactor, bitsetToString(inputTarget.pointerIds).c_str(),
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003236 inputTarget.getPointerInfoString().c_str());
3237 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003238
3239 // Skip this event if the connection status is not normal.
3240 // We don't want to enqueue additional outbound events if the connection is broken.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003241 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003242 if (DEBUG_DISPATCH_CYCLE) {
3243 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003244 connection->getInputChannelName().c_str(),
3245 ftl::enum_string(connection->status).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003246 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003247 return;
3248 }
3249
3250 // Split a motion event if needed.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003251 if (inputTarget.flags.test(InputTarget::Flags::SPLIT)) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003252 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003253 "Entry type %s should not have Flags::SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08003254 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003255
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003256 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003257 if (inputTarget.pointerIds.count() != originalMotionEntry.getPointerCount()) {
Siarhei Vishniakou16e4fa02023-02-16 17:48:56 -08003258 if (!inputTarget.firstDownTimeInTarget.has_value()) {
3259 logDispatchStateLocked();
3260 LOG(FATAL) << "Splitting motion events requires a down time to be set for the "
3261 "target on connection "
3262 << connection->getInputChannelName() << " for "
3263 << originalMotionEntry.getDescription();
3264 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003265 std::unique_ptr<MotionEntry> splitMotionEntry =
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00003266 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds,
3267 inputTarget.firstDownTimeInTarget.value());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003268 if (!splitMotionEntry) {
3269 return; // split event was dropped
3270 }
Arthur Hungb3307ee2021-10-14 10:57:37 +00003271 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
3272 std::string reason = std::string("reason=pointer cancel on split window");
3273 android_log_event_list(LOGTAG_INPUT_CANCEL)
3274 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3275 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003276 if (DEBUG_FOCUS) {
3277 ALOGD("channel '%s' ~ Split motion event.",
3278 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003279 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003280 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003281 enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection,
3282 std::move(splitMotionEntry),
3283 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003284 return;
3285 }
3286 }
3287
3288 // Not splitting. Enqueue dispatch entries for the event as is.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003289 enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection, eventEntry,
3290 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003291}
3292
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003293void InputDispatcher::enqueueDispatchEntryAndStartDispatchCycleLocked(
3294 nsecs_t currentTime, const std::shared_ptr<Connection>& connection,
3295 std::shared_ptr<const EventEntry> eventEntry, const InputTarget& inputTarget) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003296 ATRACE_NAME_IF(ATRACE_ENABLED(),
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003297 StringPrintf("enqueueDispatchEntryAndStartDispatchCycleLocked(inputChannel=%s, "
3298 "id=0x%" PRIx32 ")",
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003299 connection->getInputChannelName().c_str(), eventEntry->id));
Michael Wright3dd60e22019-03-27 22:06:44 +00003300
hongzuo liu95785e22022-09-06 02:51:35 +00003301 const bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003302
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003303 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003304
3305 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003306 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003307 startDispatchCycleLocked(currentTime, connection);
3308 }
3309}
3310
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003311void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,
Prabir Pradhan24047542023-11-02 17:14:59 +00003312 std::shared_ptr<const EventEntry> eventEntry,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003313 const InputTarget& inputTarget) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003314 // This is a new event.
3315 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003316 std::unique_ptr<DispatchEntry> dispatchEntry =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003317 createDispatchEntry(inputTarget, eventEntry, inputTarget.flags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003319 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
3320 // different EventEntry than what was passed in.
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003321 eventEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003322 // Apply target flags and update the connection's input state.
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003323 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003324 case EventEntry::Type::KEY: {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003325 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*eventEntry);
3326 if (!connection->inputState.trackKey(keyEntry, keyEntry.flags)) {
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -07003327 LOG(WARNING) << "channel " << connection->getInputChannelName()
3328 << "~ dropping inconsistent event: " << *dispatchEntry;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003329 return; // skip the inconsistent event
3330 }
3331 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003332 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003333
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003334 case EventEntry::Type::MOTION: {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003335 std::shared_ptr<const MotionEntry> resolvedMotion =
3336 std::static_pointer_cast<const MotionEntry>(eventEntry);
3337 {
3338 // Determine the resolved motion entry.
3339 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
3340 int32_t resolvedAction = motionEntry.action;
3341 int32_t resolvedFlags = motionEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003342
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003343 if (inputTarget.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003344 resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003345 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003346 resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003347 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_ENTER) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003348 resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003349 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_EXIT) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003350 resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003351 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_ENTER) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003352 resolvedAction = AMOTION_EVENT_ACTION_DOWN;
3353 }
3354 if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
3355 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3356 motionEntry.displayId)) {
3357 if (DEBUG_DISPATCH_CYCLE) {
3358 LOG(DEBUG) << "channel '" << connection->getInputChannelName().c_str()
3359 << "' ~ enqueueDispatchEntryLocked: filling in missing hover "
3360 "enter event";
3361 }
3362 resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3363 }
3364
3365 if (resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
3366 resolvedFlags |= AMOTION_EVENT_FLAG_CANCELED;
3367 }
3368 if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) {
3369 resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3370 }
3371 if (dispatchEntry->targetFlags.test(
3372 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED)) {
3373 resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3374 }
3375
3376 dispatchEntry->resolvedFlags = resolvedFlags;
3377 if (resolvedAction != motionEntry.action) {
3378 // Generate a new MotionEntry with a new eventId using the resolved action and
3379 // flags.
3380 resolvedMotion =
3381 std::make_shared<MotionEntry>(mIdGenerator.nextId(),
3382 motionEntry.injectionState,
3383 motionEntry.eventTime,
3384 motionEntry.deviceId, motionEntry.source,
3385 motionEntry.displayId,
3386 motionEntry.policyFlags, resolvedAction,
3387 motionEntry.actionButton, resolvedFlags,
3388 motionEntry.metaState,
3389 motionEntry.buttonState,
3390 motionEntry.classification,
3391 motionEntry.edgeFlags,
3392 motionEntry.xPrecision,
3393 motionEntry.yPrecision,
3394 motionEntry.xCursorPosition,
3395 motionEntry.yCursorPosition,
3396 motionEntry.downTime,
3397 motionEntry.pointerProperties,
3398 motionEntry.pointerCoords);
3399 if (ATRACE_ENABLED()) {
3400 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3401 ") to MotionEvent(id=0x%" PRIx32 ").",
3402 motionEntry.id, resolvedMotion->id);
3403 ATRACE_NAME(message.c_str());
3404 }
3405
3406 // Set the resolved motion entry in the DispatchEntry.
3407 dispatchEntry->eventEntry = resolvedMotion;
3408 eventEntry = resolvedMotion;
3409 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003410 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003411
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003412 // Check if we need to cancel any of the ongoing gestures. We don't support multiple
3413 // devices being active at the same time in the same window, so if a new device is
3414 // active, cancel the gesture from the old device.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003415 std::unique_ptr<EventEntry> cancelEvent =
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003416 connection->inputState.cancelConflictingInputStream(*resolvedMotion);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003417 if (cancelEvent != nullptr) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003418 LOG(INFO) << "Canceling pointers for device " << resolvedMotion->deviceId << " in "
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003419 << connection->getInputChannelName() << " with event "
3420 << cancelEvent->getDescription();
3421 std::unique_ptr<DispatchEntry> cancelDispatchEntry =
3422 createDispatchEntry(inputTarget, std::move(cancelEvent),
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003423 ftl::Flags<InputTarget::Flags>());
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003424
3425 // Send these cancel events to the queue before sending the event from the new
3426 // device.
3427 connection->outboundQueue.emplace_back(std::move(cancelDispatchEntry));
3428 }
3429
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003430 if (!connection->inputState.trackMotion(*resolvedMotion,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003431 dispatchEntry->resolvedFlags)) {
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -07003432 LOG(WARNING) << "channel " << connection->getInputChannelName()
3433 << "~ dropping inconsistent event: " << *dispatchEntry;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003434 return; // skip the inconsistent event
3435 }
3436
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003437 if ((resolvedMotion->flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3438 (resolvedMotion->policyFlags & POLICY_FLAG_TRUSTED)) {
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003439 // Skip reporting pointer down outside focus to the policy.
3440 break;
3441 }
3442
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003443 dispatchPointerDownOutsideFocus(resolvedMotion->source, resolvedMotion->action,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003444 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003445
3446 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003447 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003448 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003449 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003450 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3451 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003452 break;
3453 }
Chris Yef59a2f42020-10-16 12:55:26 -07003454 case EventEntry::Type::SENSOR: {
3455 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3456 break;
3457 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003458 case EventEntry::Type::CONFIGURATION_CHANGED:
3459 case EventEntry::Type::DEVICE_RESET: {
3460 LOG_ALWAYS_FATAL("%s events should not go to apps",
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003461 ftl::enum_string(eventEntry->type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003462 break;
3463 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003464 }
3465
3466 // Remember that we are waiting for this dispatch to complete.
3467 if (dispatchEntry->hasForegroundTarget()) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003468 incrementPendingForegroundDispatches(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003469 }
3470
3471 // Enqueue the dispatch entry.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003472 connection->outboundQueue.emplace_back(std::move(dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003473 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003474}
3475
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003476/**
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003477 * This function is for debugging and metrics collection. It has two roles.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003478 *
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003479 * The first role is to log input interaction with windows, which helps determine what the user was
3480 * interacting with. For example, if user is touching launcher, we will see an input_interaction log
3481 * that user started interacting with launcher window, as well as any other window that received
3482 * that gesture, such as the wallpaper or other spy windows. A new input_interaction is only logged
3483 * when the set of tokens that received the event changes. It is not logged again as long as the
3484 * user is interacting with the same windows.
3485 *
3486 * The second role is to track input device activity for metrics collection. For each input event,
3487 * we report the set of UIDs that the input device interacted with to the policy. Unlike for the
3488 * input_interaction logs, the device interaction is reported even when the set of interaction
3489 * tokens do not change.
3490 *
3491 * For these purposes, we do not count ACTION_OUTSIDE, ACTION_UP and ACTION_CANCEL actions as
3492 * interaction. This includes up and cancel events for both keys and motions.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003493 */
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003494void InputDispatcher::processInteractionsLocked(const EventEntry& entry,
3495 const std::vector<InputTarget>& targets) {
3496 int32_t deviceId;
3497 nsecs_t eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003498 // Skip ACTION_UP events, and all events other than keys and motions
3499 if (entry.type == EventEntry::Type::KEY) {
3500 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3501 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3502 return;
3503 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003504 deviceId = keyEntry.deviceId;
3505 eventTime = keyEntry.eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003506 } else if (entry.type == EventEntry::Type::MOTION) {
3507 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3508 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003509 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
3510 MotionEvent::getActionMasked(motionEntry.action) == AMOTION_EVENT_ACTION_POINTER_UP) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003511 return;
3512 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003513 deviceId = motionEntry.deviceId;
3514 eventTime = motionEntry.eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003515 } else {
3516 return; // Not a key or a motion
3517 }
3518
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003519 std::set<gui::Uid> interactionUids;
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003520 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003521 std::vector<std::shared_ptr<Connection>> newConnections;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003522 for (const InputTarget& target : targets) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003523 if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003524 continue; // Skip windows that receive ACTION_OUTSIDE
3525 }
3526
3527 sp<IBinder> token = target.inputChannel->getConnectionToken();
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003528 std::shared_ptr<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003529 if (connection == nullptr) {
3530 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003531 }
3532 newConnectionTokens.insert(std::move(token));
3533 newConnections.emplace_back(connection);
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003534 if (target.windowHandle) {
3535 interactionUids.emplace(target.windowHandle->getInfo()->ownerUid);
3536 }
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003537 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003538
3539 auto command = [this, deviceId, eventTime, uids = std::move(interactionUids)]()
3540 REQUIRES(mLock) {
3541 scoped_unlock unlock(mLock);
3542 mPolicy.notifyDeviceInteraction(deviceId, eventTime, uids);
3543 };
3544 postCommandLocked(std::move(command));
3545
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003546 if (newConnectionTokens == mInteractionConnectionTokens) {
3547 return; // no change
3548 }
3549 mInteractionConnectionTokens = newConnectionTokens;
3550
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003551 std::string targetList;
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003552 for (const std::shared_ptr<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003553 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003554 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003555 std::string message = "Interaction with: " + targetList;
3556 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003557 message += "<none>";
3558 }
3559 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3560}
3561
chaviwfd6d3512019-03-25 13:23:49 -07003562void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003563 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003564 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003565 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3566 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003567 return;
3568 }
3569
Vishnu Nairc519ff72021-01-21 08:23:08 -08003570 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003571 if (focusedToken == token) {
3572 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003573 return;
3574 }
3575
Prabir Pradhancef936d2021-07-21 16:17:52 +00003576 auto command = [this, token]() REQUIRES(mLock) {
3577 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003578 mPolicy.onPointerDownOutsideFocus(token);
Prabir Pradhancef936d2021-07-21 16:17:52 +00003579 };
3580 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003581}
3582
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003583status_t InputDispatcher::publishMotionEvent(Connection& connection,
3584 DispatchEntry& dispatchEntry) const {
3585 const EventEntry& eventEntry = *(dispatchEntry.eventEntry);
3586 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3587
3588 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003589 const PointerCoords* usingCoords = motionEntry.pointerCoords.data();
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003590
3591 // Set the X and Y offset and X and Y scale depending on the input source.
3592 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003593 !(dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS))) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003594 float globalScaleFactor = dispatchEntry.globalScaleFactor;
3595 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003596 for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003597 scaledCoords[i] = motionEntry.pointerCoords[i];
3598 // Don't apply window scale here since we don't want scale to affect raw
3599 // coordinates. The scale will be sent back to the client and applied
3600 // later when requesting relative coordinates.
Harry Cutts33476232023-01-30 19:57:29 +00003601 scaledCoords[i].scale(globalScaleFactor, /*windowXScale=*/1, /*windowYScale=*/1);
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003602 }
3603 usingCoords = scaledCoords;
3604 }
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003605 } else if (dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS)) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003606 // We don't want the dispatch target to know the coordinates
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003607 for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003608 scaledCoords[i].clear();
3609 }
3610 usingCoords = scaledCoords;
3611 }
3612
3613 std::array<uint8_t, 32> hmac = getSignature(motionEntry, dispatchEntry);
3614
3615 // Publish the motion event.
3616 return connection.inputPublisher
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003617 .publishMotionEvent(dispatchEntry.seq, motionEntry.id, motionEntry.deviceId,
3618 motionEntry.source, motionEntry.displayId, std::move(hmac),
3619 motionEntry.action, motionEntry.actionButton,
3620 dispatchEntry.resolvedFlags, motionEntry.edgeFlags,
3621 motionEntry.metaState, motionEntry.buttonState,
3622 motionEntry.classification, dispatchEntry.transform,
3623 motionEntry.xPrecision, motionEntry.yPrecision,
3624 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
3625 dispatchEntry.rawTransform, motionEntry.downTime,
3626 motionEntry.eventTime, motionEntry.getPointerCount(),
3627 motionEntry.pointerProperties.data(), usingCoords);
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003628}
3629
Michael Wrightd02c5b62014-02-10 15:10:22 -08003630void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003631 const std::shared_ptr<Connection>& connection) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003632 ATRACE_NAME_IF(ATRACE_ENABLED(),
3633 StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
3634 connection->getInputChannelName().c_str()));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003635 if (DEBUG_DISPATCH_CYCLE) {
3636 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3637 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003638
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003639 while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003640 std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003641 dispatchEntry->deliveryTime = currentTime;
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08003642 const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003643 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003644
3645 // Publish the event.
3646 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003647 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3648 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003649 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003650 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3651 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003652 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003653 LOG(INFO) << "Publishing " << *dispatchEntry << " to "
3654 << connection->getInputChannelName();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003655 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003656
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003657 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003658 status = connection->inputPublisher
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003659 .publishKeyEvent(dispatchEntry->seq, keyEntry.id,
3660 keyEntry.deviceId, keyEntry.source,
3661 keyEntry.displayId, std::move(hmac),
3662 keyEntry.action, dispatchEntry->resolvedFlags,
3663 keyEntry.keyCode, keyEntry.scanCode,
3664 keyEntry.metaState, keyEntry.repeatCount,
3665 keyEntry.downTime, keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003666 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003667 }
3668
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003669 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003670 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003671 LOG(INFO) << "Publishing " << *dispatchEntry << " to "
3672 << connection->getInputChannelName();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003673 }
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003674 status = publishMotionEvent(*connection, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003675 break;
3676 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003677
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003678 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003679 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003680 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003681 focusEntry.id,
Antonio Kantek3cfec7b2021-11-05 18:26:17 -07003682 focusEntry.hasFocus);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003683 break;
3684 }
3685
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003686 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3687 const TouchModeEntry& touchModeEntry =
3688 static_cast<const TouchModeEntry&>(eventEntry);
3689 status = connection->inputPublisher
3690 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3691 touchModeEntry.inTouchMode);
3692
3693 break;
3694 }
3695
Prabir Pradhan99987712020-11-10 18:43:05 -08003696 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3697 const auto& captureEntry =
3698 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3699 status = connection->inputPublisher
3700 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003701 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003702 break;
3703 }
3704
arthurhungb89ccb02020-12-30 16:19:01 +08003705 case EventEntry::Type::DRAG: {
3706 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3707 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3708 dragEntry.id, dragEntry.x,
3709 dragEntry.y,
3710 dragEntry.isExiting);
3711 break;
3712 }
3713
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003714 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003715 case EventEntry::Type::DEVICE_RESET:
3716 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003717 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003718 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003719 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003720 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003721 }
3722
3723 // Check the result.
3724 if (status) {
3725 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003726 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003727 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003728 "This is unexpected because the wait queue is empty, so the pipe "
3729 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003730 "event to it, status=%s(%d)",
3731 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3732 status);
Harry Cutts33476232023-01-30 19:57:29 +00003733 abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003734 } else {
3735 // Pipe is full and we are waiting for the app to finish process some events
3736 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003737 if (DEBUG_DISPATCH_CYCLE) {
3738 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3739 "waiting for the application to catch up",
3740 connection->getInputChannelName().c_str());
3741 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003742 }
3743 } else {
3744 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003745 "status=%s(%d)",
3746 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3747 status);
Harry Cutts33476232023-01-30 19:57:29 +00003748 abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003749 }
3750 return;
3751 }
3752
3753 // Re-enqueue the event on the wait queue.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003754 const nsecs_t timeoutTime = dispatchEntry->timeoutTime;
3755 connection->waitQueue.emplace_back(std::move(dispatchEntry));
3756 connection->outboundQueue.erase(connection->outboundQueue.begin());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003757 traceOutboundQueueLength(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003758 if (connection->responsive) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003759 mAnrTracker.insert(timeoutTime, connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003760 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003761 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003762 }
3763}
3764
chaviw09c8d2d2020-08-24 15:48:26 -07003765std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3766 size_t size;
3767 switch (event.type) {
3768 case VerifiedInputEvent::Type::KEY: {
3769 size = sizeof(VerifiedKeyEvent);
3770 break;
3771 }
3772 case VerifiedInputEvent::Type::MOTION: {
3773 size = sizeof(VerifiedMotionEvent);
3774 break;
3775 }
3776 }
3777 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3778 return mHmacKeyManager.sign(start, size);
3779}
3780
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003781const std::array<uint8_t, 32> InputDispatcher::getSignature(
3782 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003783 const int32_t actionMasked = MotionEvent::getActionMasked(motionEntry.action);
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003784 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003785 // Only sign events up and down events as the purely move events
3786 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003787 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003788 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003789
3790 VerifiedMotionEvent verifiedEvent =
3791 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3792 verifiedEvent.actionMasked = actionMasked;
3793 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3794 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003795}
3796
3797const std::array<uint8_t, 32> InputDispatcher::getSignature(
3798 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3799 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3800 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003801 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003802}
3803
Michael Wrightd02c5b62014-02-10 15:10:22 -08003804void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003805 const std::shared_ptr<Connection>& connection,
3806 uint32_t seq, bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003807 if (DEBUG_DISPATCH_CYCLE) {
3808 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3809 connection->getInputChannelName().c_str(), seq, toString(handled));
3810 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003811
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003812 if (connection->status == Connection::Status::BROKEN ||
3813 connection->status == Connection::Status::ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003814 return;
3815 }
3816
3817 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003818 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3819 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3820 };
3821 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003822}
3823
3824void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003825 const std::shared_ptr<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003826 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003827 if (DEBUG_DISPATCH_CYCLE) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003828 LOG(INFO) << "channel '" << connection->getInputChannelName() << "'~ " << __func__
3829 << " - notify=" << toString(notify);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003830 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003831
3832 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003833 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003834 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003835 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003836 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003837
3838 // The connection appears to be unrecoverably broken.
3839 // Ignore already broken or zombie connections.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003840 if (connection->status == Connection::Status::NORMAL) {
3841 connection->status = Connection::Status::BROKEN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003842
3843 if (notify) {
3844 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003845 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3846 connection->getInputChannelName().c_str());
3847
3848 auto command = [this, connection]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003849 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003850 mPolicy.notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Prabir Pradhancef936d2021-07-21 16:17:52 +00003851 };
3852 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003853 }
3854 }
3855}
3856
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003857void InputDispatcher::drainDispatchQueue(std::deque<std::unique_ptr<DispatchEntry>>& queue) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003858 while (!queue.empty()) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003859 releaseDispatchEntry(std::move(queue.front()));
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003860 queue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003861 }
3862}
3863
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003864void InputDispatcher::releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003866 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003867 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003868}
3869
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003870int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3871 std::scoped_lock _l(mLock);
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003872 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003873 if (connection == nullptr) {
3874 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3875 connectionToken.get(), events);
3876 return 0; // remove the callback
3877 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003878
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003879 bool notify;
3880 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3881 if (!(events & ALOOPER_EVENT_INPUT)) {
3882 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3883 "events=0x%x",
3884 connection->getInputChannelName().c_str(), events);
3885 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003886 }
3887
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003888 nsecs_t currentTime = now();
3889 bool gotOne = false;
3890 status_t status = OK;
3891 for (;;) {
3892 Result<InputPublisher::ConsumerResponse> result =
3893 connection->inputPublisher.receiveConsumerResponse();
3894 if (!result.ok()) {
3895 status = result.error().code();
3896 break;
3897 }
3898
3899 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3900 const InputPublisher::Finished& finish =
3901 std::get<InputPublisher::Finished>(*result);
3902 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3903 finish.consumeTime);
3904 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003905 if (shouldReportMetricsForConnection(*connection)) {
3906 const InputPublisher::Timeline& timeline =
3907 std::get<InputPublisher::Timeline>(*result);
3908 mLatencyTracker
3909 .trackGraphicsLatency(timeline.inputEventId,
3910 connection->inputChannel->getConnectionToken(),
3911 std::move(timeline.graphicsTimeline));
3912 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003913 }
3914 gotOne = true;
3915 }
3916 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003917 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003918 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003919 return 1;
3920 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003921 }
3922
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003923 notify = status != DEAD_OBJECT || !connection->monitor;
3924 if (notify) {
3925 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3926 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3927 status);
3928 }
3929 } else {
3930 // Monitor channels are never explicitly unregistered.
3931 // We do it automatically when the remote endpoint is closed so don't warn about them.
3932 const bool stillHaveWindowHandle =
3933 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3934 notify = !connection->monitor && stillHaveWindowHandle;
3935 if (notify) {
3936 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3937 connection->getInputChannelName().c_str(), events);
3938 }
3939 }
3940
3941 // Remove the channel.
3942 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3943 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003944}
3945
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003946void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003947 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003948 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003949 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003950 }
3951}
3952
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003953void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003954 const CancelationOptions& options) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08003955 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003956 for (const Monitor& monitor : monitors) {
3957 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003958 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003959 }
3960}
3961
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003963 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003964 std::shared_ptr<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003965 if (connection == nullptr) {
3966 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003967 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003968
3969 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003970}
3971
3972void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003973 const std::shared_ptr<Connection>& connection, const CancelationOptions& options) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003974 if (connection->status == Connection::Status::BROKEN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003975 return;
3976 }
3977
3978 nsecs_t currentTime = now();
3979
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003980 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003981 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003982
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003983 if (cancelationEvents.empty()) {
3984 return;
3985 }
Vaibhav Devmurari110ba322023-11-17 10:47:16 +00003986
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003987 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3988 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Siarhei Vishniakou2e3e4432023-02-09 18:34:11 -08003989 "with reality: %s, mode=%s.",
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003990 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
Siarhei Vishniakou2e3e4432023-02-09 18:34:11 -08003991 ftl::enum_string(options.mode).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003992 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003993
Arthur Hungb3307ee2021-10-14 10:57:37 +00003994 std::string reason = std::string("reason=").append(options.reason);
3995 android_log_event_list(LOGTAG_INPUT_CANCEL)
3996 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3997
hongzuo liu95785e22022-09-06 02:51:35 +00003998 const bool wasEmpty = connection->outboundQueue.empty();
Prabir Pradhan16463382023-10-12 23:03:19 +00003999 // The target to use if we don't find a window associated with the channel.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004000 const InputTarget fallbackTarget{.inputChannel = connection->inputChannel};
Prabir Pradhan16463382023-10-12 23:03:19 +00004001 const auto& token = connection->inputChannel->getConnectionToken();
hongzuo liu95785e22022-09-06 02:51:35 +00004002
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004003 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004004 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004005 std::vector<InputTarget> targets{};
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004006
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004007 switch (cancelationEventEntry->type) {
4008 case EventEntry::Type::KEY: {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004009 const auto& keyEntry = static_cast<const KeyEntry&>(*cancelationEventEntry);
Prabir Pradhan16463382023-10-12 23:03:19 +00004010 const std::optional<int32_t> targetDisplay = keyEntry.displayId != ADISPLAY_ID_NONE
4011 ? std::make_optional(keyEntry.displayId)
4012 : std::nullopt;
4013 if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004014 addWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
4015 /*targetFlags=*/{}, keyEntry.downTime, targets);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004016 } else {
4017 targets.emplace_back(fallbackTarget);
4018 }
4019 logOutboundKeyDetails("cancel - ", keyEntry);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004020 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004021 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004022 case EventEntry::Type::MOTION: {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004023 const auto& motionEntry = static_cast<const MotionEntry&>(*cancelationEventEntry);
Prabir Pradhan16463382023-10-12 23:03:19 +00004024 const std::optional<int32_t> targetDisplay =
4025 motionEntry.displayId != ADISPLAY_ID_NONE
4026 ? std::make_optional(motionEntry.displayId)
4027 : std::nullopt;
4028 if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004029 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004030 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004031 pointerIndex++) {
4032 pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4033 }
Vaibhav Devmurari110ba322023-11-17 10:47:16 +00004034 if (mDragState && mDragState->dragWindow->getToken() == token &&
4035 pointerIds.test(mDragState->pointerId)) {
4036 LOG(INFO) << __func__
4037 << ": Canceling drag and drop because the pointers for the drag "
4038 "window are being canceled.";
4039 sendDropWindowCommandLocked(nullptr, /*x=*/0, /*y=*/0);
4040 mDragState.reset();
4041 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004042 addPointerWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
4043 ftl::Flags<InputTarget::Flags>(), pointerIds,
4044 motionEntry.downTime, targets);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004045 } else {
4046 targets.emplace_back(fallbackTarget);
4047 const auto it = mDisplayInfos.find(motionEntry.displayId);
4048 if (it != mDisplayInfos.end()) {
4049 targets.back().displayTransform = it->second.transform;
4050 targets.back().setDefaultPointerTransform(it->second.transform);
4051 }
4052 }
4053 logOutboundMotionDetails("cancel - ", motionEntry);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004054 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004055 }
Prabir Pradhan99987712020-11-10 18:43:05 -08004056 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004057 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08004058 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
4059 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08004060 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08004061 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004062 break;
4063 }
4064 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07004065 case EventEntry::Type::DEVICE_RESET:
4066 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004067 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08004068 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004069 break;
4070 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004071 }
4072
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004073 if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004074 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), targets[0]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004075 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004076
hongzuo liu95785e22022-09-06 02:51:35 +00004077 // If the outbound queue was previously empty, start the dispatch cycle going.
4078 if (wasEmpty && !connection->outboundQueue.empty()) {
4079 startDispatchCycleLocked(currentTime, connection);
4080 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004081}
4082
Svet Ganov5d3bc372020-01-26 23:11:07 -08004083void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07004084 const nsecs_t downTime, const std::shared_ptr<Connection>& connection,
Arthur Hungc539dbb2022-12-08 07:45:36 +00004085 ftl::Flags<InputTarget::Flags> targetFlags) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08004086 if (connection->status == Connection::Status::BROKEN) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004087 return;
4088 }
4089
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004090 std::vector<std::unique_ptr<EventEntry>> downEvents =
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004091 connection->inputState.synthesizePointerDownEvents(downTime);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004092
4093 if (downEvents.empty()) {
4094 return;
4095 }
4096
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004097 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004098 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
4099 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004100 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08004101
chaviw98318de2021-05-19 16:45:23 -05004102 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08004103 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Svet Ganov5d3bc372020-01-26 23:11:07 -08004104
hongzuo liu95785e22022-09-06 02:51:35 +00004105 const bool wasEmpty = connection->outboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004106 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004107 std::vector<InputTarget> targets{};
Svet Ganov5d3bc372020-01-26 23:11:07 -08004108 switch (downEventEntry->type) {
4109 case EventEntry::Type::MOTION: {
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004110 const auto& motionEntry = static_cast<const MotionEntry&>(*downEventEntry);
4111 if (windowHandle != nullptr) {
4112 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004113 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004114 pointerIndex++) {
4115 pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4116 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004117 addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::AS_IS,
4118 targetFlags, pointerIds, motionEntry.downTime,
4119 targets);
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004120 } else {
4121 targets.emplace_back(InputTarget{.inputChannel = connection->inputChannel,
4122 .flags = targetFlags});
4123 const auto it = mDisplayInfos.find(motionEntry.displayId);
4124 if (it != mDisplayInfos.end()) {
4125 targets.back().displayTransform = it->second.transform;
4126 targets.back().setDefaultPointerTransform(it->second.transform);
4127 }
4128 }
4129 logOutboundMotionDetails("down - ", motionEntry);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004130 break;
4131 }
4132
4133 case EventEntry::Type::KEY:
4134 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004135 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08004136 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08004137 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07004138 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08004139 case EventEntry::Type::SENSOR:
4140 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004141 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08004142 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08004143 break;
4144 }
4145 }
4146
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004147 if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004148 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), targets[0]);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004149 }
4150
hongzuo liu95785e22022-09-06 02:51:35 +00004151 // If the outbound queue was previously empty, start the dispatch cycle going.
4152 if (wasEmpty && !connection->outboundQueue.empty()) {
4153 startDispatchCycleLocked(downTime, connection);
4154 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08004155}
4156
Arthur Hungc539dbb2022-12-08 07:45:36 +00004157void InputDispatcher::synthesizeCancelationEventsForWindowLocked(
4158 const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options) {
4159 if (windowHandle != nullptr) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07004160 std::shared_ptr<Connection> wallpaperConnection =
4161 getConnectionLocked(windowHandle->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00004162 if (wallpaperConnection != nullptr) {
4163 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection, options);
4164 }
4165 }
4166}
4167
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004168std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004169 const MotionEntry& originalMotionEntry, std::bitset<MAX_POINTER_ID + 1> pointerIds,
4170 nsecs_t splitDownTime) {
4171 ALOG_ASSERT(pointerIds.any());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004172
4173 uint32_t splitPointerIndexMap[MAX_POINTERS];
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004174 std::vector<PointerProperties> splitPointerProperties;
4175 std::vector<PointerCoords> splitPointerCoords;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004176
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004177 uint32_t originalPointerCount = originalMotionEntry.getPointerCount();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004178 uint32_t splitPointerCount = 0;
4179
4180 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004181 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004182 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004183 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004184 uint32_t pointerId = uint32_t(pointerProperties.id);
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004185 if (pointerIds.test(pointerId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004186 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004187 splitPointerProperties.push_back(pointerProperties);
4188 splitPointerCoords.push_back(originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004189 splitPointerCount += 1;
4190 }
4191 }
4192
4193 if (splitPointerCount != pointerIds.count()) {
4194 // This is bad. We are missing some of the pointers that we expected to deliver.
4195 // Most likely this indicates that we received an ACTION_MOVE events that has
4196 // different pointer ids than we expected based on the previous ACTION_DOWN
4197 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
4198 // in this way.
4199 ALOGW("Dropping split motion event because the pointer count is %d but "
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004200 "we expected there to be %zu pointers. This probably means we received "
Siarhei Vishniakou16e4fa02023-02-16 17:48:56 -08004201 "a broken sequence of pointer ids from the input device: %s",
4202 splitPointerCount, pointerIds.count(), originalMotionEntry.getDescription().c_str());
Yi Kong9b14ac62018-07-17 13:48:38 -07004203 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004204 }
4205
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004206 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004207 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004208 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
4209 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07004210 int32_t originalPointerIndex = MotionEvent::getActionIndex(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004211 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004212 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004213 uint32_t pointerId = uint32_t(pointerProperties.id);
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004214 if (pointerIds.test(pointerId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004215 if (pointerIds.count() == 1) {
4216 // The first/last pointer went down/up.
4217 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004218 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08004219 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
4220 ? AMOTION_EVENT_ACTION_CANCEL
4221 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004222 } else {
4223 // A secondary pointer went down/up.
4224 uint32_t splitPointerIndex = 0;
4225 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
4226 splitPointerIndex += 1;
4227 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004228 action = maskedAction |
4229 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004230 }
4231 } else {
4232 // An unrelated pointer changed.
4233 action = AMOTION_EVENT_ACTION_MOVE;
4234 }
4235 }
4236
Siarhei Vishniakou59e302b2023-06-05 08:04:53 -07004237 if (action == AMOTION_EVENT_ACTION_DOWN && splitDownTime != originalMotionEntry.eventTime) {
4238 logDispatchStateLocked();
4239 LOG_ALWAYS_FATAL("Split motion event has mismatching downTime and eventTime for "
4240 "ACTION_DOWN, motionEntry=%s, splitDownTime=%" PRId64,
4241 originalMotionEntry.getDescription().c_str(), splitDownTime);
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004242 }
4243
Garfield Tanff1f1bb2020-01-28 13:24:04 -08004244 int32_t newId = mIdGenerator.nextId();
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00004245 ATRACE_NAME_IF(ATRACE_ENABLED(),
4246 StringPrintf("Split MotionEvent(id=0x%" PRIx32 ") to MotionEvent(id=0x%" PRIx32
4247 ").",
4248 originalMotionEntry.id, newId));
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004249 std::unique_ptr<MotionEntry> splitMotionEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004250 std::make_unique<MotionEntry>(newId, originalMotionEntry.injectionState,
4251 originalMotionEntry.eventTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004252 originalMotionEntry.deviceId, originalMotionEntry.source,
4253 originalMotionEntry.displayId,
4254 originalMotionEntry.policyFlags, action,
4255 originalMotionEntry.actionButton,
4256 originalMotionEntry.flags, originalMotionEntry.metaState,
4257 originalMotionEntry.buttonState,
4258 originalMotionEntry.classification,
4259 originalMotionEntry.edgeFlags,
4260 originalMotionEntry.xPrecision,
4261 originalMotionEntry.yPrecision,
4262 originalMotionEntry.xCursorPosition,
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004263 originalMotionEntry.yCursorPosition, splitDownTime,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004264 splitPointerProperties, splitPointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004265
Michael Wrightd02c5b62014-02-10 15:10:22 -08004266 return splitMotionEntry;
4267}
4268
Asmita Poddardd9a6cd2023-09-26 15:35:12 +00004269void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
4270 std::scoped_lock _l(mLock);
4271 mLatencyTracker.setInputDevices(args.inputDeviceInfos);
4272}
4273
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004274void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004275 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004276 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args.eventTime);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004277 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004278
Antonio Kantekf16f2832021-09-28 04:39:20 +00004279 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004280 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004281 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004282
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004283 std::unique_ptr<ConfigurationChangedEntry> newEntry =
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004284 std::make_unique<ConfigurationChangedEntry>(args.id, args.eventTime);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004285 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004286 } // release lock
4287
4288 if (needWake) {
4289 mLooper->wake();
4290 }
4291}
4292
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004293void InputDispatcher::notifyKey(const NotifyKeyArgs& args) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004294 ALOGD_IF(debugInboundEventDetails(),
4295 "notifyKey - id=%" PRIx32 ", eventTime=%" PRId64
4296 ", deviceId=%d, source=%s, displayId=%" PRId32
4297 "policyFlags=0x%x, action=%s, flags=0x%x, keyCode=%s, scanCode=0x%x, metaState=0x%x, "
4298 "downTime=%" PRId64,
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004299 args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4300 args.displayId, args.policyFlags, KeyEvent::actionToString(args.action), args.flags,
4301 KeyEvent::getLabel(args.keyCode), args.scanCode, args.metaState, args.downTime);
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004302 Result<void> keyCheck = validateKeyEvent(args.action);
4303 if (!keyCheck.ok()) {
4304 LOG(ERROR) << "invalid key event: " << keyCheck.error();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004305 return;
4306 }
4307
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004308 uint32_t policyFlags = args.policyFlags;
4309 int32_t flags = args.flags;
4310 int32_t metaState = args.metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07004311 // InputDispatcher tracks and generates key repeats on behalf of
4312 // whatever notifies it, so repeatCount should always be set to 0
4313 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004314 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
4315 policyFlags |= POLICY_FLAG_VIRTUAL;
4316 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
4317 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004318 if (policyFlags & POLICY_FLAG_FUNCTION) {
4319 metaState |= AMETA_FUNCTION_ON;
4320 }
4321
4322 policyFlags |= POLICY_FLAG_TRUSTED;
4323
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004324 int32_t keyCode = args.keyCode;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004325 KeyEvent event;
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004326 event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC, args.action,
4327 flags, keyCode, args.scanCode, metaState, repeatCount, args.downTime,
4328 args.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004329
Michael Wright2b3c3302018-03-02 17:19:13 +00004330 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004331 mPolicy.interceptKeyBeforeQueueing(event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004332 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4333 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004334 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004335 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004336
Antonio Kantekf16f2832021-09-28 04:39:20 +00004337 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004338 { // acquire lock
4339 mLock.lock();
4340
4341 if (shouldSendKeyToInputFilterLocked(args)) {
4342 mLock.unlock();
4343
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004344 policyFlags |= POLICY_FLAG_FILTERED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004345 if (!mPolicy.filterInputEvent(event, policyFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004346 return; // event was consumed by the filter
4347 }
4348
4349 mLock.lock();
4350 }
4351
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004352 std::unique_ptr<KeyEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004353 std::make_unique<KeyEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4354 args.deviceId, args.source, args.displayId, policyFlags,
4355 args.action, flags, keyCode, args.scanCode, metaState,
4356 repeatCount, args.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004357
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004358 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004359 mLock.unlock();
4360 } // release lock
4361
4362 if (needWake) {
4363 mLooper->wake();
4364 }
4365}
4366
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004367bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs& args) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004368 return mInputFilterEnabled;
4369}
4370
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004371void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004372 if (debugInboundEventDetails()) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004373 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=%s, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004374 "displayId=%" PRId32 ", policyFlags=0x%x, "
Siarhei Vishniakou6ebd0692022-10-20 15:05:45 -07004375 "action=%s, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004376 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
4377 "yCursorPosition=%f, downTime=%" PRId64,
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004378 args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4379 args.displayId, args.policyFlags, MotionEvent::actionToString(args.action).c_str(),
4380 args.actionButton, args.flags, args.metaState, args.buttonState, args.edgeFlags,
4381 args.xPrecision, args.yPrecision, args.xCursorPosition, args.yCursorPosition,
4382 args.downTime);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004383 for (uint32_t i = 0; i < args.getPointerCount(); i++) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004384 ALOGD(" Pointer %d: id=%d, toolType=%s, x=%f, y=%f, pressure=%f, size=%f, "
4385 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, orientation=%f",
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004386 i, args.pointerProperties[i].id,
4387 ftl::enum_string(args.pointerProperties[i].toolType).c_str(),
4388 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
4389 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
4390 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
4391 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
4392 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
4393 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
4394 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
4395 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
4396 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004397 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004398 }
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004399
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004400 Result<void> motionCheck =
4401 validateMotionEvent(args.action, args.actionButton, args.getPointerCount(),
4402 args.pointerProperties.data());
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004403 if (!motionCheck.ok()) {
4404 LOG(FATAL) << "Invalid event: " << args.dump() << "; reason: " << motionCheck.error();
4405 return;
4406 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004407
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07004408 if (DEBUG_VERIFY_EVENTS) {
4409 auto [it, _] =
4410 mVerifiersByDisplay.try_emplace(args.displayId,
4411 StringPrintf("display %" PRId32, args.displayId));
4412 Result<void> result =
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -07004413 it->second.processMovement(args.deviceId, args.source, args.action,
4414 args.getPointerCount(), args.pointerProperties.data(),
4415 args.pointerCoords.data(), args.flags);
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07004416 if (!result.ok()) {
4417 LOG(FATAL) << "Bad stream: " << result.error() << " caused by " << args.dump();
4418 }
4419 }
4420
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004421 uint32_t policyFlags = args.policyFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004422 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004423
4424 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004425 mPolicy.interceptMotionBeforeQueueing(args.displayId, args.eventTime, policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004426 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4427 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004428 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004429 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004430
Antonio Kantekf16f2832021-09-28 04:39:20 +00004431 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004432 { // acquire lock
4433 mLock.lock();
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004434 if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
4435 // Set the flag anyway if we already have an ongoing gesture. That would allow us to
4436 // complete the processing of the current stroke.
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004437 const auto touchStateIt = mTouchStatesByDisplay.find(args.displayId);
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004438 if (touchStateIt != mTouchStatesByDisplay.end()) {
4439 const TouchState& touchState = touchStateIt->second;
Linnan Li907ae732023-09-05 17:14:21 +08004440 if (touchState.hasTouchingPointers(args.deviceId) ||
4441 touchState.hasHoveringPointers(args.deviceId)) {
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004442 policyFlags |= POLICY_FLAG_PASS_TO_USER;
4443 }
4444 }
4445 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004446
4447 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004448 ui::Transform displayTransform;
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004449 if (const auto it = mDisplayInfos.find(args.displayId); it != mDisplayInfos.end()) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004450 displayTransform = it->second.transform;
4451 }
4452
Michael Wrightd02c5b62014-02-10 15:10:22 -08004453 mLock.unlock();
4454
4455 MotionEvent event;
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004456 event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC,
4457 args.action, args.actionButton, args.flags, args.edgeFlags,
4458 args.metaState, args.buttonState, args.classification,
4459 displayTransform, args.xPrecision, args.yPrecision,
4460 args.xCursorPosition, args.yCursorPosition, displayTransform,
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004461 args.downTime, args.eventTime, args.getPointerCount(),
4462 args.pointerProperties.data(), args.pointerCoords.data());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004463
4464 policyFlags |= POLICY_FLAG_FILTERED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004465 if (!mPolicy.filterInputEvent(event, policyFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004466 return; // event was consumed by the filter
4467 }
4468
4469 mLock.lock();
4470 }
4471
4472 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004473 std::unique_ptr<MotionEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004474 std::make_unique<MotionEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4475 args.deviceId, args.source, args.displayId,
4476 policyFlags, args.action, args.actionButton,
4477 args.flags, args.metaState, args.buttonState,
4478 args.classification, args.edgeFlags, args.xPrecision,
4479 args.yPrecision, args.xCursorPosition,
4480 args.yCursorPosition, args.downTime,
4481 args.pointerProperties, args.pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004482
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004483 if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4484 IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004485 !mInputFilterEnabled) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004486 const bool isDown = args.action == AMOTION_EVENT_ACTION_DOWN;
Asmita Poddardd9a6cd2023-09-26 15:35:12 +00004487 std::set<InputDeviceUsageSource> sources = getUsageSourcesForMotionArgs(args);
4488 mLatencyTracker.trackListener(args.id, isDown, args.eventTime, args.readTime,
4489 args.deviceId, sources);
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004490 }
4491
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004492 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004493 mLock.unlock();
4494 } // release lock
4495
4496 if (needWake) {
4497 mLooper->wake();
4498 }
4499}
4500
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004501void InputDispatcher::notifySensor(const NotifySensorArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004502 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004503 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4504 " sensorType=%s",
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004505 args.id, args.eventTime, args.deviceId, args.source,
4506 ftl::enum_string(args.sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004507 }
Chris Yef59a2f42020-10-16 12:55:26 -07004508
Antonio Kantekf16f2832021-09-28 04:39:20 +00004509 bool needWake = false;
Chris Yef59a2f42020-10-16 12:55:26 -07004510 { // acquire lock
4511 mLock.lock();
4512
4513 // Just enqueue a new sensor event.
4514 std::unique_ptr<SensorEntry> newEntry =
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004515 std::make_unique<SensorEntry>(args.id, args.eventTime, args.deviceId, args.source,
4516 /* policyFlags=*/0, args.hwTimestamp, args.sensorType,
4517 args.accuracy, args.accuracyChanged, args.values);
Chris Yef59a2f42020-10-16 12:55:26 -07004518
4519 needWake = enqueueInboundEventLocked(std::move(newEntry));
4520 mLock.unlock();
4521 } // release lock
4522
4523 if (needWake) {
4524 mLooper->wake();
4525 }
4526}
4527
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004528void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004529 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004530 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args.eventTime,
4531 args.deviceId, args.isOn);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004532 }
Prabir Pradhana41d2442023-04-20 21:30:40 +00004533 mPolicy.notifyVibratorState(args.deviceId, args.isOn);
Chris Yefb552902021-02-03 17:18:37 -08004534}
4535
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004536bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs& args) {
Jackal Guof9696682018-10-05 12:23:23 +08004537 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004538}
4539
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004540void InputDispatcher::notifySwitch(const NotifySwitchArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004541 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004542 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4543 "switchMask=0x%08x",
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004544 args.eventTime, args.policyFlags, args.switchValues, args.switchMask);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004545 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004546
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004547 uint32_t policyFlags = args.policyFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004548 policyFlags |= POLICY_FLAG_TRUSTED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004549 mPolicy.notifySwitch(args.eventTime, args.switchValues, args.switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004550}
4551
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004552void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004553 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004554 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args.eventTime,
4555 args.deviceId);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004556 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004557
Antonio Kantekf16f2832021-09-28 04:39:20 +00004558 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004559 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004560 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004561
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004562 std::unique_ptr<DeviceResetEntry> newEntry =
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004563 std::make_unique<DeviceResetEntry>(args.id, args.eventTime, args.deviceId);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004564 needWake = enqueueInboundEventLocked(std::move(newEntry));
Siarhei Vishniakou1160ecd2023-06-28 15:57:47 -07004565
4566 for (auto& [_, verifier] : mVerifiersByDisplay) {
4567 verifier.resetDevice(args.deviceId);
4568 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004569 } // release lock
4570
4571 if (needWake) {
4572 mLooper->wake();
4573 }
4574}
4575
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004576void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004577 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004578 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args.eventTime,
4579 args.request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004580 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004581
Antonio Kantekf16f2832021-09-28 04:39:20 +00004582 bool needWake = false;
Prabir Pradhan99987712020-11-10 18:43:05 -08004583 { // acquire lock
4584 std::scoped_lock _l(mLock);
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004585 auto entry =
4586 std::make_unique<PointerCaptureChangedEntry>(args.id, args.eventTime, args.request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004587 needWake = enqueueInboundEventLocked(std::move(entry));
4588 } // release lock
4589
4590 if (needWake) {
4591 mLooper->wake();
4592 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004593}
4594
Prabir Pradhan5735a322022-04-11 17:23:34 +00004595InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* event,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00004596 std::optional<gui::Uid> targetUid,
Prabir Pradhan5735a322022-04-11 17:23:34 +00004597 InputEventInjectionSync syncMode,
4598 std::chrono::milliseconds timeout,
4599 uint32_t policyFlags) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004600 Result<void> eventValidation = validateInputEvent(*event);
4601 if (!eventValidation.ok()) {
4602 LOG(INFO) << "Injection failed: invalid event: " << eventValidation.error();
4603 return InputEventInjectionResult::FAILED;
4604 }
4605
Prabir Pradhan65613802023-02-22 23:36:58 +00004606 if (debugInboundEventDetails()) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004607 LOG(INFO) << __func__ << ": targetUid=" << toString(targetUid, &uidString)
4608 << ", syncMode=" << ftl::enum_string(syncMode) << ", timeout=" << timeout.count()
4609 << "ms, policyFlags=0x" << std::hex << policyFlags << std::dec
4610 << ", event=" << *event;
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004611 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004612 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004613
Prabir Pradhan5735a322022-04-11 17:23:34 +00004614 policyFlags |= POLICY_FLAG_INJECTED | POLICY_FLAG_TRUSTED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004615
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004616 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004617 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4618 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4619 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4620 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4621 // from events that originate from actual hardware.
Siarhei Vishniakouf4043212023-09-18 19:33:03 -07004622 DeviceId resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004623 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004624 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004625 }
4626
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004627 const bool isAsync = syncMode == InputEventInjectionSync::NONE;
4628 auto injectionState = std::make_shared<InjectionState>(targetUid, isAsync);
4629
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004630 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004631 switch (event->getType()) {
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004632 case InputEventType::KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004633 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004634 const int32_t action = incomingKey.getAction();
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004635 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004636 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4637 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4638 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004639 int32_t keyCode = incomingKey.getKeyCode();
4640 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004641 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004642 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004643 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4644 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4645 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004646
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004647 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4648 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004649 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004650
4651 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4652 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004653 mPolicy.interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004654 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4655 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4656 std::to_string(t.duration().count()).c_str());
4657 }
4658 }
4659
4660 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004661 std::unique_ptr<KeyEntry> injectedEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004662 std::make_unique<KeyEntry>(incomingKey.getId(), injectionState,
4663 incomingKey.getEventTime(), resolvedDeviceId,
4664 incomingKey.getSource(), incomingKey.getDisplayId(),
4665 policyFlags, action, flags, keyCode,
4666 incomingKey.getScanCode(), metaState,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004667 incomingKey.getRepeatCount(),
4668 incomingKey.getDownTime());
4669 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004670 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004671 }
4672
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004673 case InputEventType::MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004674 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004675 const bool isPointerEvent =
4676 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4677 // If a pointer event has no displayId specified, inject it to the default display.
4678 const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
4679 ? ADISPLAY_ID_DEFAULT
4680 : event->getDisplayId();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004681 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004682
4683 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004684 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004685 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004686 mPolicy.interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004687 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4688 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4689 std::to_string(t.duration().count()).c_str());
4690 }
4691 }
4692
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004693 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4694 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4695 }
4696
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004697 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004698 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004699 const size_t pointerCount = motionEvent.getPointerCount();
4700 const std::vector<PointerProperties>
4701 pointerProperties(motionEvent.getPointerProperties(),
4702 motionEvent.getPointerProperties() + pointerCount);
4703
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004704 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004705 std::unique_ptr<MotionEntry> injectedEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004706 std::make_unique<MotionEntry>(motionEvent.getId(), injectionState,
4707 *sampleEventTimes, resolvedDeviceId,
4708 motionEvent.getSource(), displayId, policyFlags,
4709 motionEvent.getAction(),
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004710 motionEvent.getActionButton(), flags,
4711 motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004712 motionEvent.getButtonState(),
4713 motionEvent.getClassification(),
4714 motionEvent.getEdgeFlags(),
4715 motionEvent.getXPrecision(),
4716 motionEvent.getYPrecision(),
4717 motionEvent.getRawXCursorPosition(),
4718 motionEvent.getRawYCursorPosition(),
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004719 motionEvent.getDownTime(), pointerProperties,
4720 std::vector<PointerCoords>(samplePointerCoords,
4721 samplePointerCoords +
4722 pointerCount));
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004723 transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004724 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004725 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004726 sampleEventTimes += 1;
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004727 samplePointerCoords += motionEvent.getPointerCount();
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004728 std::unique_ptr<MotionEntry> nextInjectedEntry = std::make_unique<
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004729 MotionEntry>(motionEvent.getId(), injectionState, *sampleEventTimes,
4730 resolvedDeviceId, motionEvent.getSource(), displayId,
4731 policyFlags, motionEvent.getAction(),
4732 motionEvent.getActionButton(), flags,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004733 motionEvent.getMetaState(), motionEvent.getButtonState(),
4734 motionEvent.getClassification(), motionEvent.getEdgeFlags(),
4735 motionEvent.getXPrecision(), motionEvent.getYPrecision(),
4736 motionEvent.getRawXCursorPosition(),
4737 motionEvent.getRawYCursorPosition(), motionEvent.getDownTime(),
4738 pointerProperties,
4739 std::vector<PointerCoords>(samplePointerCoords,
4740 samplePointerCoords +
4741 pointerCount));
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004742 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
4743 motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004744 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004745 }
4746 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004747 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004748
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004749 default:
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004750 LOG(WARNING) << "Cannot inject " << ftl::enum_string(event->getType()) << " events";
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004751 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004752 }
4753
Michael Wrightd02c5b62014-02-10 15:10:22 -08004754 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004755 while (!injectedEntries.empty()) {
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08004756 if (DEBUG_INJECTION) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004757 LOG(INFO) << "Injecting " << injectedEntries.front()->getDescription();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08004758 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004759 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004760 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004761 }
4762
4763 mLock.unlock();
4764
4765 if (needWake) {
4766 mLooper->wake();
4767 }
4768
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004769 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004770 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004771 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004772
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004773 if (syncMode == InputEventInjectionSync::NONE) {
4774 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004775 } else {
4776 for (;;) {
4777 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004778 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004779 break;
4780 }
4781
4782 nsecs_t remainingTimeout = endTime - now();
4783 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004784 if (DEBUG_INJECTION) {
4785 ALOGD("injectInputEvent - Timed out waiting for injection result "
4786 "to become available.");
4787 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004788 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004789 break;
4790 }
4791
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004792 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004793 }
4794
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004795 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4796 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004797 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004798 if (DEBUG_INJECTION) {
4799 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4800 injectionState->pendingForegroundDispatches);
4801 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004802 nsecs_t remainingTimeout = endTime - now();
4803 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004804 if (DEBUG_INJECTION) {
4805 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4806 "dispatches to finish.");
4807 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004808 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004809 break;
4810 }
4811
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004812 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004813 }
4814 }
4815 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004816 } // release lock
4817
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004818 if (DEBUG_INJECTION) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004819 LOG(INFO) << "injectInputEvent - Finished with result "
4820 << ftl::enum_string(injectionResult);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004821 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004822
4823 return injectionResult;
4824}
4825
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004826std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004827 std::array<uint8_t, 32> calculatedHmac;
4828 std::unique_ptr<VerifiedInputEvent> result;
4829 switch (event.getType()) {
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004830 case InputEventType::KEY: {
Gang Wange9087892020-01-07 12:17:14 -05004831 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4832 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4833 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004834 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004835 break;
4836 }
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004837 case InputEventType::MOTION: {
Gang Wange9087892020-01-07 12:17:14 -05004838 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4839 VerifiedMotionEvent verifiedMotionEvent =
4840 verifiedMotionEventFromMotionEvent(motionEvent);
4841 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004842 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004843 break;
4844 }
4845 default: {
4846 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4847 return nullptr;
4848 }
4849 }
4850 if (calculatedHmac == INVALID_HMAC) {
4851 return nullptr;
4852 }
tyiu1573a672023-02-21 22:38:32 +00004853 if (0 != CRYPTO_memcmp(calculatedHmac.data(), event.getHmac().data(), calculatedHmac.size())) {
Gang Wange9087892020-01-07 12:17:14 -05004854 return nullptr;
4855 }
4856 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004857}
4858
Prabir Pradhan24047542023-11-02 17:14:59 +00004859void InputDispatcher::setInjectionResult(const EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004860 InputEventInjectionResult injectionResult) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004861 if (!entry.injectionState) {
4862 // Not an injected event.
4863 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004864 }
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004865
4866 InjectionState& injectionState = *entry.injectionState;
4867 if (DEBUG_INJECTION) {
4868 LOG(INFO) << "Setting input event injection result to "
4869 << ftl::enum_string(injectionResult);
4870 }
4871
4872 if (injectionState.injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
4873 // Log the outcome since the injector did not wait for the injection result.
4874 switch (injectionResult) {
4875 case InputEventInjectionResult::SUCCEEDED:
4876 ALOGV("Asynchronous input event injection succeeded.");
4877 break;
4878 case InputEventInjectionResult::TARGET_MISMATCH:
4879 ALOGV("Asynchronous input event injection target mismatch.");
4880 break;
4881 case InputEventInjectionResult::FAILED:
4882 ALOGW("Asynchronous input event injection failed.");
4883 break;
4884 case InputEventInjectionResult::TIMED_OUT:
4885 ALOGW("Asynchronous input event injection timed out.");
4886 break;
4887 case InputEventInjectionResult::PENDING:
4888 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4889 break;
4890 }
4891 }
4892
4893 injectionState.injectionResult = injectionResult;
4894 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004895}
4896
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004897void InputDispatcher::transformMotionEntryForInjectionLocked(
4898 MotionEntry& entry, const ui::Transform& injectedTransform) const {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004899 // Input injection works in the logical display coordinate space, but the input pipeline works
4900 // display space, so we need to transform the injected events accordingly.
4901 const auto it = mDisplayInfos.find(entry.displayId);
4902 if (it == mDisplayInfos.end()) return;
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004903 const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004904
Prabir Pradhand9a2ebe2022-07-20 19:25:13 +00004905 if (entry.xCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
4906 entry.yCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
4907 const vec2 cursor =
4908 MotionEvent::calculateTransformedXY(entry.source, transformToDisplay,
4909 {entry.xCursorPosition, entry.yCursorPosition});
4910 entry.xCursorPosition = cursor.x;
4911 entry.yCursorPosition = cursor.y;
4912 }
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004913 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
Prabir Pradhan8e6ce222022-02-24 09:08:54 -08004914 entry.pointerCoords[i] =
4915 MotionEvent::calculateTransformedCoords(entry.source, transformToDisplay,
4916 entry.pointerCoords[i]);
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004917 }
4918}
4919
Prabir Pradhan24047542023-11-02 17:14:59 +00004920void InputDispatcher::incrementPendingForegroundDispatches(const EventEntry& entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004921 if (entry.injectionState) {
4922 entry.injectionState->pendingForegroundDispatches += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004923 }
4924}
4925
Prabir Pradhan24047542023-11-02 17:14:59 +00004926void InputDispatcher::decrementPendingForegroundDispatches(const EventEntry& entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004927 if (entry.injectionState) {
4928 entry.injectionState->pendingForegroundDispatches -= 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004929
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004930 if (entry.injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004931 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004932 }
4933 }
4934}
4935
chaviw98318de2021-05-19 16:45:23 -05004936const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004937 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004938 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004939 auto it = mWindowHandlesByDisplay.find(displayId);
4940 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004941}
4942
chaviw98318de2021-05-19 16:45:23 -05004943sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
Prabir Pradhan16463382023-10-12 23:03:19 +00004944 const sp<IBinder>& windowHandleToken, std::optional<int32_t> displayId) const {
arthurhungbe737672020-06-24 12:29:21 +08004945 if (windowHandleToken == nullptr) {
4946 return nullptr;
4947 }
4948
Prabir Pradhan16463382023-10-12 23:03:19 +00004949 if (!displayId) {
4950 // Look through all displays.
4951 for (auto& it : mWindowHandlesByDisplay) {
4952 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4953 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
4954 if (windowHandle->getToken() == windowHandleToken) {
4955 return windowHandle;
4956 }
Arthur Hungb92218b2018-08-14 12:00:21 +08004957 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004958 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07004959 return nullptr;
4960 }
4961
Prabir Pradhan16463382023-10-12 23:03:19 +00004962 // Only look through the requested display.
4963 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(*displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004964 if (windowHandle->getToken() == windowHandleToken) {
4965 return windowHandle;
4966 }
4967 }
4968 return nullptr;
4969}
4970
chaviw98318de2021-05-19 16:45:23 -05004971sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4972 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004973 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004974 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4975 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004976 if (handle->getId() == windowHandle->getId() &&
4977 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004978 if (windowHandle->getInfo()->displayId != it.first) {
4979 ALOGE("Found window %s in display %" PRId32
4980 ", but it should belong to display %" PRId32,
4981 windowHandle->getName().c_str(), it.first,
4982 windowHandle->getInfo()->displayId);
4983 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004984 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004985 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004986 }
4987 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004988 return nullptr;
4989}
4990
chaviw98318de2021-05-19 16:45:23 -05004991sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004992 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4993 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004994}
4995
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00004996ui::Transform InputDispatcher::getTransformLocked(int32_t displayId) const {
4997 auto displayInfoIt = mDisplayInfos.find(displayId);
4998 return displayInfoIt != mDisplayInfos.end() ? displayInfoIt->second.transform
4999 : kIdentityTransform;
5000}
5001
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005002bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& window,
5003 const MotionEntry& motionEntry) const {
5004 const WindowInfo& info = *window->getInfo();
5005
5006 // Skip spy window targets that are not valid for targeted injection.
5007 if (const auto err = verifyTargetedInjection(window, motionEntry); err) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005008 return false;
5009 }
5010
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005011 if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
5012 ALOGI("Not sending touch event to %s because it is paused", window->getName().c_str());
5013 return false;
5014 }
5015
5016 if (info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL)) {
5017 ALOGW("Not sending touch gesture to %s because it has config NO_INPUT_CHANNEL",
5018 window->getName().c_str());
5019 return false;
5020 }
5021
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005022 std::shared_ptr<Connection> connection = getConnectionLocked(window->getToken());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005023 if (connection == nullptr) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005024 ALOGW("Not sending touch to %s because there's no corresponding connection",
5025 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005026 return false;
5027 }
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005028
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005029 if (!connection->responsive) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005030 ALOGW("Not sending touch to %s because it is not responsive", window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005031 return false;
5032 }
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005033
5034 // Drop events that can't be trusted due to occlusion
5035 const auto [x, y] = resolveTouchedPosition(motionEntry);
5036 TouchOcclusionInfo occlusionInfo = computeTouchOcclusionInfoLocked(window, x, y);
5037 if (!isTouchTrustedLocked(occlusionInfo)) {
5038 if (DEBUG_TOUCH_OCCLUSION) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00005039 ALOGD("Stack of obscuring windows during untrusted touch (%.1f, %.1f):", x, y);
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005040 for (const auto& log : occlusionInfo.debugInfo) {
5041 ALOGD("%s", log.c_str());
5042 }
5043 }
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00005044 ALOGW("Dropping untrusted touch event due to %s/%s", occlusionInfo.obscuringPackage.c_str(),
5045 occlusionInfo.obscuringUid.toString().c_str());
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005046 return false;
5047 }
5048
5049 // Drop touch events if requested by input feature
5050 if (shouldDropInput(motionEntry, window)) {
5051 return false;
5052 }
5053
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005054 return true;
5055}
5056
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005057std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
5058 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005059 auto connectionIt = mConnectionsByToken.find(token);
5060 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07005061 return nullptr;
5062 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005063 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07005064}
5065
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005066void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05005067 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
5068 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005069 // Remove all handles on a display if there are no windows left.
5070 mWindowHandlesByDisplay.erase(displayId);
5071 return;
5072 }
5073
5074 // Since we compare the pointer of input window handles across window updates, we need
5075 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05005076 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
5077 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
5078 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07005079 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005080 }
5081
chaviw98318de2021-05-19 16:45:23 -05005082 std::vector<sp<WindowInfoHandle>> newHandles;
5083 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05005084 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005085 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005086 const bool noInputChannel =
Prabir Pradhan51e7db02022-02-07 06:02:57 -08005087 info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005088 const bool canReceiveInput =
5089 !info->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) ||
5090 !info->inputConfig.test(WindowInfo::InputConfig::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005091 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07005092 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005093 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07005094 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005095 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005096 }
5097
5098 if (info->displayId != displayId) {
5099 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
5100 handle->getName().c_str(), displayId, info->displayId);
5101 continue;
5102 }
5103
Robert Carredd13602020-04-13 17:24:34 -07005104 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
5105 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05005106 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005107 oldHandle->updateFrom(handle);
5108 newHandles.push_back(oldHandle);
5109 } else {
5110 newHandles.push_back(handle);
5111 }
5112 }
5113
5114 // Insert or replace
5115 mWindowHandlesByDisplay[displayId] = newHandles;
5116}
5117
Arthur Hungb92218b2018-08-14 12:00:21 +08005118/**
5119 * Called from InputManagerService, update window handle list by displayId that can receive input.
5120 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
5121 * If set an empty list, remove all handles from the specific display.
5122 * For focused handle, check if need to change and send a cancel event to previous one.
5123 * For removed handle, check if need to send a cancel event if already in touch.
5124 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00005125void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05005126 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005127 if (DEBUG_FOCUS) {
5128 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05005129 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005130 windowList += iwh->getName() + " ";
5131 }
Siarhei Vishniakou366fb5b2023-12-06 11:23:41 -08005132 LOG(INFO) << "setInputWindows displayId=" << displayId << " " << windowList;
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005133 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005134
Prabir Pradhand65552b2021-10-07 11:23:50 -07005135 // Check preconditions for new input windows
chaviw98318de2021-05-19 16:45:23 -05005136 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07005137 const WindowInfo& info = *window->getInfo();
5138
5139 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
Prabir Pradhan51e7db02022-02-07 06:02:57 -08005140 const bool noInputWindow = info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005141 if (noInputWindow && window->getToken() != nullptr) {
5142 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
5143 window->getName().c_str());
5144 window->releaseChannel();
5145 }
Prabir Pradhand65552b2021-10-07 11:23:50 -07005146
Prabir Pradhan5c85e052021-12-22 02:27:12 -08005147 // Ensure all spy windows are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005148 LOG_ALWAYS_FATAL_IF(info.isSpy() &&
5149 !info.inputConfig.test(
5150 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhan5c85e052021-12-22 02:27:12 -08005151 "%s has feature SPY, but is not a trusted overlay.",
5152 window->getName().c_str());
5153
Prabir Pradhand65552b2021-10-07 11:23:50 -07005154 // Ensure all stylus interceptors are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005155 LOG_ALWAYS_FATAL_IF(info.interceptsStylus() &&
5156 !info.inputConfig.test(
5157 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhand65552b2021-10-07 11:23:50 -07005158 "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
5159 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005160 }
5161
Arthur Hung72d8dc32020-03-28 00:48:39 +00005162 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05005163 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005164
chaviw98318de2021-05-19 16:45:23 -05005165 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005166
chaviw98318de2021-05-19 16:45:23 -05005167 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00005168
Vishnu Nairc519ff72021-01-21 08:23:08 -08005169 std::optional<FocusResolver::FocusChanges> changes =
5170 mFocusResolver.setInputWindows(displayId, windowHandles);
5171 if (changes) {
5172 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00005173 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005174
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005175 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5176 mTouchStatesByDisplay.find(displayId);
5177 if (stateIt != mTouchStatesByDisplay.end()) {
5178 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00005179 for (size_t i = 0; i < state.windows.size();) {
5180 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005181 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07005182 LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName()
5183 << " in display %" << displayId;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005184 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00005185 getInputChannelLocked(touchedWindow.windowHandle->getToken());
5186 if (touchedInputChannel != nullptr) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00005187 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Arthur Hung72d8dc32020-03-28 00:48:39 +00005188 "touched window was removed");
5189 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005190 // Since we are about to drop the touch, cancel the events for the wallpaper as
5191 // well.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005192 if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005193 touchedWindow.windowHandle->getInfo()->inputConfig.test(
5194 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005195 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
Arthur Hungc539dbb2022-12-08 07:45:36 +00005196 synthesizeCancelationEventsForWindowLocked(wallpaper, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005197 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005198 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005199 state.windows.erase(state.windows.begin() + i);
5200 } else {
5201 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005202 }
5203 }
arthurhungb89ccb02020-12-30 16:19:01 +08005204
arthurhung6d4bed92021-03-17 11:59:33 +08005205 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08005206 // could just clear the state here.
Arthur Hung3915c1f2022-05-31 07:17:17 +00005207 if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId &&
arthurhung6d4bed92021-03-17 11:59:33 +08005208 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08005209 windowHandles.end()) {
Arthur Hung3915c1f2022-05-31 07:17:17 +00005210 ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str());
5211 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08005212 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08005213 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005214 }
Arthur Hung25e2af12020-03-26 12:58:37 +00005215
Arthur Hung72d8dc32020-03-28 00:48:39 +00005216 // Release information for windows that are no longer present.
5217 // This ensures that unused input channels are released promptly.
5218 // Otherwise, they might stick around until the window handle is destroyed
5219 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05005220 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005221 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00005222 if (DEBUG_FOCUS) {
5223 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00005224 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005225 oldWindowHandle->releaseChannel();
Arthur Hung25e2af12020-03-26 12:58:37 +00005226 }
chaviw291d88a2019-02-14 10:33:58 -08005227 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005228}
5229
5230void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07005231 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005232 if (DEBUG_FOCUS) {
5233 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
5234 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
5235 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005236 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005237 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07005238 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005239 } // release lock
5240
5241 // Wake up poll loop since it may need to make new input dispatching choices.
5242 mLooper->wake();
5243}
5244
Vishnu Nair599f1412021-06-21 10:39:58 -07005245void InputDispatcher::setFocusedApplicationLocked(
5246 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
5247 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
5248 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
5249
5250 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
5251 return; // This application is already focused. No need to wake up or change anything.
5252 }
5253
5254 // Set the new application handle.
5255 if (inputApplicationHandle != nullptr) {
5256 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
5257 } else {
5258 mFocusedApplicationHandlesByDisplay.erase(displayId);
5259 }
5260
5261 // No matter what the old focused application was, stop waiting on it because it is
5262 // no longer focused.
5263 resetNoFocusedWindowTimeoutLocked();
5264}
5265
Tiger Huang721e26f2018-07-24 22:26:19 +08005266/**
5267 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
5268 * the display not specified.
5269 *
5270 * We track any unreleased events for each window. If a window loses the ability to receive the
5271 * released event, we will send a cancel event to it. So when the focused display is changed, we
5272 * cancel all the unreleased display-unspecified events for the focused window on the old focused
5273 * display. The display-specified events won't be affected.
5274 */
5275void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005276 if (DEBUG_FOCUS) {
5277 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
5278 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005279 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005280 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08005281
5282 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005283 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08005284 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005285 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005286 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07005287 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08005288 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005289 CancelationOptions
Michael Wrightfb04fd52022-11-24 22:31:11 +00005290 options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005291 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005292 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08005293 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
5294 }
5295 }
5296 mFocusedDisplayId = displayId;
5297
Chris Ye3c2d6f52020-08-09 10:39:48 -07005298 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08005299 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00005300 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08005301
Vishnu Nairad321cd2020-08-20 16:40:21 -07005302 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08005303 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005304 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005305 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08005306 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08005307 }
5308 }
5309 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005310 } // release lock
5311
5312 // Wake up poll loop since it may need to make new input dispatching choices.
5313 mLooper->wake();
5314}
5315
Michael Wrightd02c5b62014-02-10 15:10:22 -08005316void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005317 if (DEBUG_FOCUS) {
5318 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
5319 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005320
5321 bool changed;
5322 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005323 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005324
5325 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
5326 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005327 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005328 }
5329
5330 if (mDispatchEnabled && !enabled) {
5331 resetAndDropEverythingLocked("dispatcher is being disabled");
5332 }
5333
5334 mDispatchEnabled = enabled;
5335 mDispatchFrozen = frozen;
5336 changed = true;
5337 } else {
5338 changed = false;
5339 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005340 } // release lock
5341
5342 if (changed) {
5343 // Wake up poll loop since it may need to make new input dispatching choices.
5344 mLooper->wake();
5345 }
5346}
5347
5348void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005349 if (DEBUG_FOCUS) {
5350 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
5351 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005352
5353 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005354 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005355
5356 if (mInputFilterEnabled == enabled) {
5357 return;
5358 }
5359
5360 mInputFilterEnabled = enabled;
5361 resetAndDropEverythingLocked("input filter is being enabled or disabled");
5362 } // release lock
5363
5364 // Wake up poll loop since there might be work to do to drop everything.
5365 mLooper->wake();
5366}
5367
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005368bool InputDispatcher::setInTouchMode(bool inTouchMode, gui::Pid pid, gui::Uid uid,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00005369 bool hasPermission, int32_t displayId) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00005370 bool needWake = false;
5371 {
5372 std::scoped_lock lock(mLock);
Antonio Kantek15beb512022-06-13 22:35:41 +00005373 ALOGD_IF(DEBUG_TOUCH_MODE,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005374 "Request to change touch mode to %s (calling pid=%s, uid=%s, "
Antonio Kantek15beb512022-06-13 22:35:41 +00005375 "hasPermission=%s, target displayId=%d, mTouchModePerDisplay[displayId]=%s)",
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005376 toString(inTouchMode), pid.toString().c_str(), uid.toString().c_str(),
5377 toString(hasPermission), displayId,
Antonio Kantek15beb512022-06-13 22:35:41 +00005378 mTouchModePerDisplay.count(displayId) == 0
5379 ? "not set"
5380 : std::to_string(mTouchModePerDisplay[displayId]).c_str());
5381
Antonio Kantek15beb512022-06-13 22:35:41 +00005382 auto touchModeIt = mTouchModePerDisplay.find(displayId);
5383 if (touchModeIt != mTouchModePerDisplay.end() && touchModeIt->second == inTouchMode) {
Antonio Kantekea47acb2021-12-23 12:41:25 -08005384 return false;
Antonio Kantekf16f2832021-09-28 04:39:20 +00005385 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005386 if (!hasPermission) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005387 if (!focusedWindowIsOwnedByLocked(pid, uid) &&
5388 !recentWindowsAreOwnedByLocked(pid, uid)) {
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005389 ALOGD("Touch mode switch rejected, caller (pid=%s, uid=%s) doesn't own the focused "
Antonio Kantek48710e42022-03-24 14:19:30 -07005390 "window nor none of the previously interacted window",
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005391 pid.toString().c_str(), uid.toString().c_str());
Antonio Kantekea47acb2021-12-23 12:41:25 -08005392 return false;
5393 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00005394 }
Antonio Kantek15beb512022-06-13 22:35:41 +00005395 mTouchModePerDisplay[displayId] = inTouchMode;
5396 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode,
5397 displayId);
Antonio Kantekf16f2832021-09-28 04:39:20 +00005398 needWake = enqueueInboundEventLocked(std::move(entry));
5399 } // release lock
5400
5401 if (needWake) {
5402 mLooper->wake();
5403 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005404 return true;
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08005405}
5406
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005407bool InputDispatcher::focusedWindowIsOwnedByLocked(gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005408 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
5409 if (focusedToken == nullptr) {
5410 return false;
5411 }
5412 sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken);
5413 return isWindowOwnedBy(windowHandle, pid, uid);
5414}
5415
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005416bool InputDispatcher::recentWindowsAreOwnedByLocked(gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005417 return std::find_if(mInteractionConnectionTokens.begin(), mInteractionConnectionTokens.end(),
5418 [&](const sp<IBinder>& connectionToken) REQUIRES(mLock) {
5419 const sp<WindowInfoHandle> windowHandle =
5420 getWindowHandleLocked(connectionToken);
5421 return isWindowOwnedBy(windowHandle, pid, uid);
5422 }) != mInteractionConnectionTokens.end();
5423}
5424
Bernardo Rufinoea97d182020-08-19 14:43:14 +01005425void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
5426 if (opacity < 0 || opacity > 1) {
5427 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
5428 return;
5429 }
5430
5431 std::scoped_lock lock(mLock);
5432 mMaximumObscuringOpacityForTouch = opacity;
5433}
5434
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005435std::tuple<TouchState*, TouchedWindow*, int32_t /*displayId*/>
5436InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) {
Arthur Hungabbb9d82021-09-01 14:52:30 +00005437 for (auto& [displayId, state] : mTouchStatesByDisplay) {
5438 for (TouchedWindow& w : state.windows) {
5439 if (w.windowHandle->getToken() == token) {
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005440 return std::make_tuple(&state, &w, displayId);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005441 }
5442 }
5443 }
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005444 return std::make_tuple(nullptr, nullptr, ADISPLAY_ID_DEFAULT);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005445}
5446
arthurhungb89ccb02020-12-30 16:19:01 +08005447bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5448 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08005449 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005450 if (DEBUG_FOCUS) {
5451 ALOGD("Trivial transfer to same window.");
5452 }
chaviwfbe5d9c2018-12-26 12:23:37 -08005453 return true;
5454 }
5455
Michael Wrightd02c5b62014-02-10 15:10:22 -08005456 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005457 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005458
Arthur Hungabbb9d82021-09-01 14:52:30 +00005459 // Find the target touch state and touched window by fromToken.
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005460 auto [state, touchedWindow, displayId] = findTouchStateWindowAndDisplayLocked(fromToken);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005461
Arthur Hungabbb9d82021-09-01 14:52:30 +00005462 if (state == nullptr || touchedWindow == nullptr) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005463 ALOGD("Touch transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005464 return false;
5465 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005466 std::set<int32_t> deviceIds = touchedWindow->getTouchingDeviceIds();
5467 if (deviceIds.size() != 1) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07005468 LOG(INFO) << "Can't transfer touch. Currently touching devices: " << dumpSet(deviceIds)
5469 << " for window: " << touchedWindow->dump();
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005470 return false;
5471 }
5472 const int32_t deviceId = *deviceIds.begin();
Arthur Hungabbb9d82021-09-01 14:52:30 +00005473
Arthur Hungabbb9d82021-09-01 14:52:30 +00005474 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
5475 if (toWindowHandle == nullptr) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005476 ALOGW("Cannot transfer touch because to window not found.");
Arthur Hungabbb9d82021-09-01 14:52:30 +00005477 return false;
5478 }
5479
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005480 if (DEBUG_FOCUS) {
5481 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00005482 touchedWindow->windowHandle->getName().c_str(),
5483 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005484 }
5485
Arthur Hungabbb9d82021-09-01 14:52:30 +00005486 // Erase old window.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005487 ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags;
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08005488 std::vector<PointerProperties> pointers = touchedWindow->getTouchingPointers(deviceId);
Arthur Hungc539dbb2022-12-08 07:45:36 +00005489 sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
Arthur Hungabbb9d82021-09-01 14:52:30 +00005490 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005491
Arthur Hungabbb9d82021-09-01 14:52:30 +00005492 // Add new window.
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00005493 nsecs_t downTimeInTarget = now();
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005494 ftl::Flags<InputTarget::Flags> newTargetFlags =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00005495 oldTargetFlags & (InputTarget::Flags::SPLIT);
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005496 if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005497 newTargetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005498 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00005499 state->addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08005500 deviceId, pointers, downTimeInTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005501
Arthur Hungabbb9d82021-09-01 14:52:30 +00005502 // Store the dragging window.
5503 if (isDragDrop) {
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08005504 if (pointers.size() != 1) {
Arthur Hungb75c2aa2022-07-15 09:35:36 +00005505 ALOGW("The drag and drop cannot be started when there is no pointer or more than 1"
5506 " pointer on the window.");
Arthur Hung54745652022-04-20 07:17:41 +00005507 return false;
5508 }
Arthur Hungb75c2aa2022-07-15 09:35:36 +00005509 // Track the pointer id for drag window and generate the drag state.
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08005510 const size_t id = pointers.begin()->id;
Arthur Hung54745652022-04-20 07:17:41 +00005511 mDragState = std::make_unique<DragState>(toWindowHandle, id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005512 }
5513
Arthur Hungabbb9d82021-09-01 14:52:30 +00005514 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005515 std::shared_ptr<Connection> fromConnection = getConnectionLocked(fromToken);
5516 std::shared_ptr<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005517 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005518 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005519 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5520 "transferring touch from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005521 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Arthur Hungc539dbb2022-12-08 07:45:36 +00005522 synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection,
5523 newTargetFlags);
5524
5525 // Check if the wallpaper window should deliver the corresponding event.
5526 transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08005527 *state, deviceId, pointers);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005528 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005529 } // release lock
5530
5531 // Wake up poll loop since it may need to make new input dispatching choices.
5532 mLooper->wake();
5533 return true;
5534}
5535
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005536/**
5537 * Get the touched foreground window on the given display.
5538 * Return null if there are no windows touched on that display, or if more than one foreground
5539 * window is being touched.
5540 */
5541sp<WindowInfoHandle> InputDispatcher::findTouchedForegroundWindowLocked(int32_t displayId) const {
5542 auto stateIt = mTouchStatesByDisplay.find(displayId);
5543 if (stateIt == mTouchStatesByDisplay.end()) {
5544 ALOGI("No touch state on display %" PRId32, displayId);
5545 return nullptr;
5546 }
5547
5548 const TouchState& state = stateIt->second;
5549 sp<WindowInfoHandle> touchedForegroundWindow;
5550 // If multiple foreground windows are touched, return nullptr
5551 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005552 if (window.targetFlags.test(InputTarget::Flags::FOREGROUND)) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005553 if (touchedForegroundWindow != nullptr) {
5554 ALOGI("Two or more foreground windows: %s and %s",
5555 touchedForegroundWindow->getName().c_str(),
5556 window.windowHandle->getName().c_str());
5557 return nullptr;
5558 }
5559 touchedForegroundWindow = window.windowHandle;
5560 }
5561 }
5562 return touchedForegroundWindow;
5563}
5564
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005565// Binder call
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005566bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken, int32_t displayId) {
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005567 sp<IBinder> fromToken;
5568 { // acquire lock
5569 std::scoped_lock _l(mLock);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005570 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005571 if (toWindowHandle == nullptr) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005572 ALOGW("Could not find window associated with token=%p on display %" PRId32,
5573 destChannelToken.get(), displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005574 return false;
5575 }
5576
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005577 sp<WindowInfoHandle> from = findTouchedForegroundWindowLocked(displayId);
5578 if (from == nullptr) {
5579 ALOGE("Could not find a source window in %s for %p", __func__, destChannelToken.get());
5580 return false;
5581 }
5582
5583 fromToken = from->getToken();
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005584 } // release lock
5585
5586 return transferTouchFocus(fromToken, destChannelToken);
5587}
5588
Michael Wrightd02c5b62014-02-10 15:10:22 -08005589void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005590 if (DEBUG_FOCUS) {
5591 ALOGD("Resetting and dropping all events (%s).", reason);
5592 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005593
Michael Wrightfb04fd52022-11-24 22:31:11 +00005594 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005595 synthesizeCancelationEventsForAllConnectionsLocked(options);
5596
5597 resetKeyRepeatLocked();
5598 releasePendingEventLocked();
5599 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005600 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005601
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005602 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005603 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005604}
5605
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005606void InputDispatcher::logDispatchStateLocked() const {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005607 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005608 dumpDispatchStateLocked(dump);
5609
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005610 std::istringstream stream(dump);
5611 std::string line;
5612
5613 while (std::getline(stream, line, '\n')) {
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07005614 ALOGI("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005615 }
5616}
5617
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005618std::string InputDispatcher::dumpPointerCaptureStateLocked() const {
Prabir Pradhan99987712020-11-10 18:43:05 -08005619 std::string dump;
5620
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005621 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5622 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005623
5624 std::string windowName = "None";
5625 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005626 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005627 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5628 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5629 : "token has capture without window";
5630 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005631 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005632
5633 return dump;
5634}
5635
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005636void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005637 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5638 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5639 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005640 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005641
Tiger Huang721e26f2018-07-24 22:26:19 +08005642 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5643 dump += StringPrintf(INDENT "FocusedApplications:\n");
5644 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5645 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005646 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005647 const std::chrono::duration timeout =
5648 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005649 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005650 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005651 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005652 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005653 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005654 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005655 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005656
Vishnu Nairc519ff72021-01-21 08:23:08 -08005657 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005658 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005659
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005660 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005661 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005662 for (const auto& [displayId, state] : mTouchStatesByDisplay) {
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -08005663 std::string touchStateDump = addLinePrefix(state.dump(), INDENT2);
5664 dump += INDENT2 + std::to_string(displayId) + " : " + touchStateDump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005665 }
5666 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005667 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005668 }
5669
arthurhung6d4bed92021-03-17 11:59:33 +08005670 if (mDragState) {
5671 dump += StringPrintf(INDENT "DragState:\n");
5672 mDragState->dump(dump, INDENT2);
5673 }
5674
Arthur Hungb92218b2018-08-14 12:00:21 +08005675 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005676 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5677 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5678 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5679 const auto& displayInfo = it->second;
5680 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5681 displayInfo.logicalHeight);
5682 displayInfo.transform.dump(dump, "transform", INDENT4);
5683 } else {
5684 dump += INDENT2 "No DisplayInfo found!\n";
5685 }
5686
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005687 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005688 dump += INDENT2 "Windows:\n";
5689 for (size_t i = 0; i < windowHandles.size(); i++) {
Siarhei Vishniakou366fb5b2023-12-06 11:23:41 -08005690 dump += StringPrintf(INDENT3 "%zu: %s", i,
5691 streamableToString(*windowHandles[i]).c_str());
Arthur Hungb92218b2018-08-14 12:00:21 +08005692 }
5693 } else {
5694 dump += INDENT2 "Windows: <none>\n";
5695 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005696 }
5697 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005698 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005699 }
5700
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005701 if (!mGlobalMonitorsByDisplay.empty()) {
5702 for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
5703 dump += StringPrintf(INDENT "Global monitors on display %d:\n", displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00005704 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005705 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005706 } else {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005707 dump += INDENT "Global Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005708 }
5709
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005710 const nsecs_t currentTime = now();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005711
5712 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005713 if (!mRecentQueue.empty()) {
5714 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Prabir Pradhan24047542023-11-02 17:14:59 +00005715 for (const std::shared_ptr<const EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005716 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005717 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005718 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005719 }
5720 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005721 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005722 }
5723
5724 // Dump event currently being dispatched.
5725 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005726 dump += INDENT "PendingEvent:\n";
5727 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005728 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005729 dump += StringPrintf(", age=%" PRId64 "ms\n",
5730 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005731 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005732 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005733 }
5734
5735 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005736 if (!mInboundQueue.empty()) {
5737 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Prabir Pradhan24047542023-11-02 17:14:59 +00005738 for (const std::shared_ptr<const EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005739 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005740 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005741 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005742 }
5743 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005744 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005745 }
5746
Prabir Pradhancef936d2021-07-21 16:17:52 +00005747 if (!mCommandQueue.empty()) {
5748 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5749 } else {
5750 dump += INDENT "CommandQueue: <empty>\n";
5751 }
5752
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005753 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005754 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005755 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005756 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005757 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005758 connection->inputChannel->getFd().get(),
5759 connection->getInputChannelName().c_str(),
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005760 connection->getWindowName().c_str(),
5761 ftl::enum_string(connection->status).c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005762 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005763
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005764 if (!connection->outboundQueue.empty()) {
5765 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5766 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005767 dump += dumpQueue(connection->outboundQueue, currentTime);
5768
Michael Wrightd02c5b62014-02-10 15:10:22 -08005769 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005770 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005771 }
5772
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005773 if (!connection->waitQueue.empty()) {
5774 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5775 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005776 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005777 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005778 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005779 }
Siarhei Vishniakou366fb5b2023-12-06 11:23:41 -08005780 std::string inputStateDump = streamableToString(connection->inputState);
5781 if (!inputStateDump.empty()) {
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -07005782 dump += INDENT3 "InputState: ";
Siarhei Vishniakou366fb5b2023-12-06 11:23:41 -08005783 dump += inputStateDump + "\n";
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -07005784 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005785 }
5786 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005787 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005788 }
5789
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07005790 dump += "input_flags::remove_app_switch_drops() = ";
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07005791 dump += toString(REMOVE_APP_SWITCH_DROPS);
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07005792 dump += "\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005793 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005794 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5795 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005796 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005797 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005798 }
5799
Antonio Kantek15beb512022-06-13 22:35:41 +00005800 if (!mTouchModePerDisplay.empty()) {
5801 dump += INDENT "TouchModePerDisplay:\n";
5802 for (const auto& [displayId, touchMode] : mTouchModePerDisplay) {
5803 dump += StringPrintf(INDENT2 "Display: %" PRId32 " TouchMode: %s\n", displayId,
5804 std::to_string(touchMode).c_str());
5805 }
5806 } else {
5807 dump += INDENT "TouchModePerDisplay: <none>\n";
5808 }
5809
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005810 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005811 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5812 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5813 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005814 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005815 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005816}
5817
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005818void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00005819 const size_t numMonitors = monitors.size();
5820 for (size_t i = 0; i < numMonitors; i++) {
5821 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005822 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005823 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5824 dump += "\n";
5825 }
5826}
5827
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005828class LooperEventCallback : public LooperCallback {
5829public:
5830 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5831 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5832
5833private:
5834 std::function<int(int events)> mCallback;
5835};
5836
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005837Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005838 if (DEBUG_CHANNEL_CREATION) {
5839 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5840 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005841
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005842 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005843 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005844 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005845
5846 if (result) {
5847 return base::Error(result) << "Failed to open input channel pair with name " << name;
5848 }
5849
Michael Wrightd02c5b62014-02-10 15:10:22 -08005850 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005851 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005852 const sp<IBinder>& token = serverChannel->getConnectionToken();
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005853 auto&& fd = serverChannel->getFd();
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005854 std::shared_ptr<Connection> connection =
5855 std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/false,
5856 mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005857
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005858 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5859 ALOGE("Created a new connection, but the token %p is already known", token.get());
5860 }
5861 mConnectionsByToken.emplace(token, connection);
5862
5863 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5864 this, std::placeholders::_1, token);
5865
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005866 mLooper->addFd(fd.get(), 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005867 nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005868 } // release lock
5869
5870 // Wake the looper because some connections have changed.
5871 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005872 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005873}
5874
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005875Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005876 const std::string& name,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005877 gui::Pid pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005878 std::shared_ptr<InputChannel> serverChannel;
5879 std::unique_ptr<InputChannel> clientChannel;
5880 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5881 if (result) {
5882 return base::Error(result) << "Failed to open input channel pair with name " << name;
5883 }
5884
Michael Wright3dd60e22019-03-27 22:06:44 +00005885 { // acquire lock
5886 std::scoped_lock _l(mLock);
5887
5888 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005889 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5890 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005891 }
5892
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005893 std::shared_ptr<Connection> connection =
5894 std::make_shared<Connection>(serverChannel, /*monitor=*/true, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005895 const sp<IBinder>& token = serverChannel->getConnectionToken();
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005896 auto&& fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005897
5898 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5899 ALOGE("Created a new connection, but the token %p is already known", token.get());
5900 }
5901 mConnectionsByToken.emplace(token, connection);
5902 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5903 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005904
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005905 mGlobalMonitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005906
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005907 mLooper->addFd(fd.get(), 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005908 nullptr);
Michael Wright3dd60e22019-03-27 22:06:44 +00005909 }
Garfield Tan15601662020-09-22 15:32:38 -07005910
Michael Wright3dd60e22019-03-27 22:06:44 +00005911 // Wake the looper because some connections have changed.
5912 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005913 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005914}
5915
Garfield Tan15601662020-09-22 15:32:38 -07005916status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005917 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005918 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005919
Harry Cutts33476232023-01-30 19:57:29 +00005920 status_t status = removeInputChannelLocked(connectionToken, /*notify=*/false);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005921 if (status) {
5922 return status;
5923 }
5924 } // release lock
5925
5926 // Wake the poll loop because removing the connection may have changed the current
5927 // synchronization state.
5928 mLooper->wake();
5929 return OK;
5930}
5931
Garfield Tan15601662020-09-22 15:32:38 -07005932status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5933 bool notify) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005934 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005935 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005936 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005937 return BAD_VALUE;
5938 }
5939
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005940 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005941
Michael Wrightd02c5b62014-02-10 15:10:22 -08005942 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005943 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005944 }
5945
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005946 mLooper->removeFd(connection->inputChannel->getFd().get());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005947
5948 nsecs_t currentTime = now();
5949 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5950
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005951 connection->status = Connection::Status::ZOMBIE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005952 return OK;
5953}
5954
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005955void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005956 for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
5957 auto& [displayId, monitors] = *it;
5958 std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
5959 return monitor.inputChannel->getConnectionToken() == connectionToken;
5960 });
Michael Wright3dd60e22019-03-27 22:06:44 +00005961
Michael Wright3dd60e22019-03-27 22:06:44 +00005962 if (monitors.empty()) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005963 it = mGlobalMonitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005964 } else {
5965 ++it;
5966 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005967 }
5968}
5969
Michael Wright3dd60e22019-03-27 22:06:44 +00005970status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005971 std::scoped_lock _l(mLock);
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00005972 return pilferPointersLocked(token);
5973}
Michael Wright3dd60e22019-03-27 22:06:44 +00005974
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00005975status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005976 const std::shared_ptr<InputChannel> requestingChannel = getInputChannelLocked(token);
5977 if (!requestingChannel) {
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07005978 LOG(WARNING)
5979 << "Attempted to pilfer pointers from an un-registered channel or invalid token";
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005980 return BAD_VALUE;
Michael Wright3dd60e22019-03-27 22:06:44 +00005981 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005982
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005983 auto [statePtr, windowPtr, displayId] = findTouchStateWindowAndDisplayLocked(token);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005984 if (statePtr == nullptr || windowPtr == nullptr) {
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07005985 LOG(WARNING)
5986 << "Attempted to pilfer points from a channel without any on-going pointer streams."
5987 " Ignoring.";
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005988 return BAD_VALUE;
5989 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005990 std::set<int32_t> deviceIds = windowPtr->getTouchingDeviceIds();
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07005991 if (deviceIds.empty()) {
5992 LOG(WARNING) << "Can't pilfer: no touching devices in window: " << windowPtr->dump();
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005993 return BAD_VALUE;
5994 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005995
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07005996 for (const DeviceId deviceId : deviceIds) {
5997 TouchState& state = *statePtr;
5998 TouchedWindow& window = *windowPtr;
5999 // Send cancel events to all the input channels we're stealing from.
6000 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6001 "input channel stole pointer stream");
6002 options.deviceId = deviceId;
6003 options.displayId = displayId;
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006004 std::vector<PointerProperties> pointers = window.getTouchingPointers(deviceId);
6005 std::bitset<MAX_POINTER_ID + 1> pointerIds = getPointerIds(pointers);
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006006 options.pointerIds = pointerIds;
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006007
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006008 std::string canceledWindows;
6009 for (const TouchedWindow& w : state.windows) {
6010 const std::shared_ptr<InputChannel> channel =
6011 getInputChannelLocked(w.windowHandle->getToken());
6012 if (channel != nullptr && channel->getConnectionToken() != token) {
6013 synthesizeCancelationEventsForInputChannelLocked(channel, options);
6014 canceledWindows += canceledWindows.empty() ? "[" : ", ";
6015 canceledWindows += channel->getName();
6016 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006017 }
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006018 canceledWindows += canceledWindows.empty() ? "[]" : "]";
6019 LOG(INFO) << "Channel " << requestingChannel->getName()
6020 << " is stealing input gesture for device " << deviceId << " from "
6021 << canceledWindows;
6022
6023 // Prevent the gesture from being sent to any other windows.
6024 // This only blocks relevant pointers to be sent to other windows
6025 window.addPilferingPointers(deviceId, pointerIds);
6026
6027 state.cancelPointersForWindowsExcept(deviceId, pointerIds, token);
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006028 }
Michael Wright3dd60e22019-03-27 22:06:44 +00006029 return OK;
6030}
6031
Prabir Pradhan99987712020-11-10 18:43:05 -08006032void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
6033 { // acquire lock
6034 std::scoped_lock _l(mLock);
6035 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05006036 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08006037 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
6038 windowHandle != nullptr ? windowHandle->getName().c_str()
6039 : "token without window");
6040 }
6041
Vishnu Nairc519ff72021-01-21 08:23:08 -08006042 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08006043 if (focusedToken != windowToken) {
6044 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
6045 enabled ? "enable" : "disable");
6046 return;
6047 }
6048
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006049 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006050 ALOGW("Ignoring request to %s Pointer Capture: "
6051 "window has %s requested pointer capture.",
6052 enabled ? "enable" : "disable", enabled ? "already" : "not");
6053 return;
6054 }
6055
Christine Franksb768bb42021-11-29 12:11:31 -08006056 if (enabled) {
6057 if (std::find(mIneligibleDisplaysForPointerCapture.begin(),
6058 mIneligibleDisplaysForPointerCapture.end(),
6059 mFocusedDisplayId) != mIneligibleDisplaysForPointerCapture.end()) {
6060 ALOGW("Ignoring request to enable Pointer Capture: display is not eligible");
6061 return;
6062 }
6063 }
6064
Prabir Pradhan99987712020-11-10 18:43:05 -08006065 setPointerCaptureLocked(enabled);
6066 } // release lock
6067
6068 // Wake the thread to process command entries.
6069 mLooper->wake();
6070}
6071
Christine Franksb768bb42021-11-29 12:11:31 -08006072void InputDispatcher::setDisplayEligibilityForPointerCapture(int32_t displayId, bool isEligible) {
6073 { // acquire lock
6074 std::scoped_lock _l(mLock);
6075 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
6076 if (!isEligible) {
6077 mIneligibleDisplaysForPointerCapture.push_back(displayId);
6078 }
6079 } // release lock
6080}
6081
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006082std::optional<gui::Pid> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006083 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00006084 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006085 if (monitor.inputChannel->getConnectionToken() == token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006086 return monitor.pid;
Michael Wright3dd60e22019-03-27 22:06:44 +00006087 }
6088 }
6089 }
6090 return std::nullopt;
6091}
6092
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006093std::shared_ptr<Connection> InputDispatcher::getConnectionLocked(
6094 const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07006095 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006096 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08006097 }
6098
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00006099 for (const auto& [token, connection] : mConnectionsByToken) {
6100 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006101 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006102 }
6103 }
Robert Carr4e670e52018-08-15 13:26:12 -07006104
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006105 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006106}
6107
Siarhei Vishniakouad991402020-10-28 11:40:09 -05006108std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006109 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakouad991402020-10-28 11:40:09 -05006110 if (connection == nullptr) {
6111 return "<nullptr>";
6112 }
6113 return connection->getInputChannelName();
6114}
6115
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006116void InputDispatcher::removeConnectionLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006117 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00006118 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07006119}
6120
Prabir Pradhancef936d2021-07-21 16:17:52 +00006121void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006122 const std::shared_ptr<Connection>& connection,
6123 uint32_t seq, bool handled,
6124 nsecs_t consumeTime) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006125 // Handle post-event policy actions.
Prabir Pradhan24047542023-11-02 17:14:59 +00006126 std::unique_ptr<const KeyEntry> fallbackKeyEntry;
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006127
6128 { // Start critical section
6129 auto dispatchEntryIt =
6130 std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6131 [seq](auto& e) { return e->seq == seq; });
6132 if (dispatchEntryIt == connection->waitQueue.end()) {
6133 return;
6134 }
6135
6136 DispatchEntry& dispatchEntry = **dispatchEntryIt;
6137
6138 const nsecs_t eventDuration = finishTime - dispatchEntry.deliveryTime;
6139 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
6140 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
6141 ns2ms(eventDuration), dispatchEntry.eventEntry->getDescription().c_str());
6142 }
6143 if (shouldReportFinishedEvent(dispatchEntry, *connection)) {
6144 mLatencyTracker.trackFinishedEvent(dispatchEntry.eventEntry->id,
6145 connection->inputChannel->getConnectionToken(),
6146 dispatchEntry.deliveryTime, consumeTime, finishTime);
6147 }
6148
6149 if (dispatchEntry.eventEntry->type == EventEntry::Type::KEY) {
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006150 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*(dispatchEntry.eventEntry));
6151 fallbackKeyEntry =
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006152 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006153 }
6154 } // End critical section: The -LockedInterruptable methods may have released the lock.
Prabir Pradhancef936d2021-07-21 16:17:52 +00006155
6156 // Dequeue the event and start the next cycle.
6157 // Because the lock might have been released, it is possible that the
6158 // contents of the wait queue to have been drained, so we need to double-check
6159 // a few things.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006160 auto entryIt = std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6161 [seq](auto& e) { return e->seq == seq; });
6162 if (entryIt != connection->waitQueue.end()) {
6163 std::unique_ptr<DispatchEntry> dispatchEntry = std::move(*entryIt);
6164 connection->waitQueue.erase(entryIt);
6165
Prabir Pradhancef936d2021-07-21 16:17:52 +00006166 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
6167 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
6168 if (!connection->responsive) {
6169 connection->responsive = isConnectionResponsive(*connection);
6170 if (connection->responsive) {
6171 // The connection was unresponsive, and now it's responsive.
6172 processConnectionResponsiveLocked(*connection);
6173 }
6174 }
6175 traceWaitQueueLength(*connection);
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006176 if (fallbackKeyEntry && connection->status == Connection::Status::NORMAL) {
6177 const InputTarget target{.inputChannel = connection->inputChannel,
6178 .flags = dispatchEntry->targetFlags};
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006179 enqueueDispatchEntryLocked(connection, std::move(fallbackKeyEntry), target);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006180 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006181 releaseDispatchEntry(std::move(dispatchEntry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00006182 }
6183
6184 // Start the next dispatch cycle for this connection.
6185 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006186}
6187
Prabir Pradhancef936d2021-07-21 16:17:52 +00006188void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
6189 const sp<IBinder>& newToken) {
6190 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
6191 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006192 mPolicy.notifyFocusChanged(oldToken, newToken);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006193 };
6194 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006195}
6196
Prabir Pradhancef936d2021-07-21 16:17:52 +00006197void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
6198 auto command = [this, token, x, y]() REQUIRES(mLock) {
6199 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006200 mPolicy.notifyDropWindow(token, x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006201 };
6202 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08006203}
6204
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006205void InputDispatcher::onAnrLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006206 if (connection == nullptr) {
6207 LOG_ALWAYS_FATAL("Caller must check for nullness");
6208 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006209 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
6210 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006211 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006212 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006213 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006214 return;
6215 }
6216 /**
6217 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
6218 * may not be the one that caused the timeout to occur. One possibility is that window timeout
6219 * has changed. This could cause newer entries to time out before the already dispatched
6220 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
6221 * processes the events linearly. So providing information about the oldest entry seems to be
6222 * most useful.
6223 */
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006224 DispatchEntry& oldestEntry = *connection->waitQueue.front();
6225 const nsecs_t currentWait = now() - oldestEntry.deliveryTime;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006226 std::string reason =
6227 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006228 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006229 ns2ms(currentWait),
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006230 oldestEntry.eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006231 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06006232 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006233
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006234 processConnectionUnresponsiveLocked(*connection, std::move(reason));
6235
6236 // Stop waking up for events on this connection, it is already unresponsive
6237 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006238}
6239
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05006240void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
6241 std::string reason =
6242 StringPrintf("%s does not have a focused window", application->getName().c_str());
6243 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006244
Yabin Cui8eb9c552023-06-08 18:05:07 +00006245 auto command = [this, app = std::move(application)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006246 scoped_unlock unlock(mLock);
Yabin Cuiced952f2023-06-09 21:12:51 +00006247 mPolicy.notifyNoFocusedWindowAnr(app);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006248 };
6249 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00006250}
6251
chaviw98318de2021-05-19 16:45:23 -05006252void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006253 const std::string& reason) {
6254 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
6255 updateLastAnrStateLocked(windowLabel, reason);
6256}
6257
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05006258void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
6259 const std::string& reason) {
6260 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006261 updateLastAnrStateLocked(windowLabel, reason);
6262}
6263
6264void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
6265 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006266 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07006267 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006268 struct tm tm;
6269 localtime_r(&t, &tm);
6270 char timestr[64];
6271 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006272 mLastAnrState.clear();
6273 mLastAnrState += INDENT "ANR:\n";
6274 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006275 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
6276 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006277 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006278}
6279
Prabir Pradhancef936d2021-07-21 16:17:52 +00006280void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
Prabir Pradhan24047542023-11-02 17:14:59 +00006281 const KeyEntry& entry) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006282 const KeyEvent event = createKeyEvent(entry);
6283 nsecs_t delay = 0;
6284 { // release lock
6285 scoped_unlock unlock(mLock);
6286 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00006287 delay = mPolicy.interceptKeyBeforeDispatching(focusedWindowToken, event, entry.policyFlags);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006288 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
6289 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
6290 std::to_string(t.duration().count()).c_str());
6291 }
6292 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08006293
6294 if (delay < 0) {
Michael Wright5caf55a2022-11-24 22:31:42 +00006295 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00006296 } else if (delay == 0) {
Michael Wright5caf55a2022-11-24 22:31:42 +00006297 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006298 } else {
Michael Wright5caf55a2022-11-24 22:31:42 +00006299 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006300 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006301 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006302}
6303
Prabir Pradhancef936d2021-07-21 16:17:52 +00006304void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006305 std::optional<gui::Pid> pid,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006306 std::string reason) {
Yabin Cui8eb9c552023-06-08 18:05:07 +00006307 auto command = [this, token, pid, r = std::move(reason)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006308 scoped_unlock unlock(mLock);
Yabin Cuiced952f2023-06-09 21:12:51 +00006309 mPolicy.notifyWindowUnresponsive(token, pid, r);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006310 };
6311 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006312}
6313
Prabir Pradhanedd96402022-02-15 01:46:16 -08006314void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006315 std::optional<gui::Pid> pid) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08006316 auto command = [this, token, pid]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006317 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006318 mPolicy.notifyWindowResponsive(token, pid);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006319 };
6320 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006321}
6322
6323/**
6324 * Tell the policy that a connection has become unresponsive so that it can start ANR.
6325 * Check whether the connection of interest is a monitor or a window, and add the corresponding
6326 * command entry to the command queue.
6327 */
6328void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
6329 std::string reason) {
6330 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006331 std::optional<gui::Pid> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006332 if (connection.monitor) {
6333 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
6334 reason.c_str());
Prabir Pradhanedd96402022-02-15 01:46:16 -08006335 pid = findMonitorPidByTokenLocked(connectionToken);
6336 } else {
6337 // The connection is a window
6338 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
6339 reason.c_str());
6340 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6341 if (handle != nullptr) {
6342 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006343 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006344 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08006345 sendWindowUnresponsiveCommandLocked(connectionToken, pid, std::move(reason));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006346}
6347
6348/**
6349 * Tell the policy that a connection has become responsive so that it can stop ANR.
6350 */
6351void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
6352 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006353 std::optional<gui::Pid> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006354 if (connection.monitor) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08006355 pid = findMonitorPidByTokenLocked(connectionToken);
6356 } else {
6357 // The connection is a window
6358 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6359 if (handle != nullptr) {
6360 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006361 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006362 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08006363 sendWindowResponsiveCommandLocked(connectionToken, pid);
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006364}
6365
Prabir Pradhan24047542023-11-02 17:14:59 +00006366std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptable(
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006367 const std::shared_ptr<Connection>& connection, DispatchEntry& dispatchEntry,
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006368 const KeyEntry& keyEntry, bool handled) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006369 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006370 if (!handled) {
6371 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006372 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006373 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006374 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006375 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006376
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006377 // Get the fallback key state.
6378 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006379 int32_t originalKeyCode = keyEntry.keyCode;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006380 std::optional<int32_t> fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006381 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006382 connection->inputState.removeFallbackKey(originalKeyCode);
6383 }
6384
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006385 if (handled || !dispatchEntry.hasForegroundTarget()) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006386 // If the application handles the original key for which we previously
6387 // generated a fallback or if the window is not a foreground window,
6388 // then cancel the associated fallback key, if any.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006389 if (fallbackKeyCode) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006390 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006391 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6392 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
6393 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6394 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
6395 keyEntry.policyFlags);
6396 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006397 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006398 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006399
6400 mLock.unlock();
6401
Prabir Pradhana41d2442023-04-20 21:30:40 +00006402 if (const auto unhandledKeyFallback =
6403 mPolicy.dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
6404 event, keyEntry.policyFlags);
6405 unhandledKeyFallback) {
6406 event = *unhandledKeyFallback;
6407 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006408
6409 mLock.lock();
6410
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006411 // Cancel the fallback key.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006412 if (*fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00006413 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006414 "application handled the original non-fallback key "
6415 "or is no longer a foreground target, "
6416 "canceling previously dispatched fallback key");
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006417 options.keyCode = *fallbackKeyCode;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006418 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006419 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006420 connection->inputState.removeFallbackKey(originalKeyCode);
6421 }
6422 } else {
6423 // If the application did not handle a non-fallback key, first check
6424 // that we are in a good state to perform unhandled key event processing
6425 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006426 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006427 if (!fallbackKeyCode && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006428 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6429 ALOGD("Unhandled key event: Skipping unhandled key event processing "
6430 "since this is not an initial down. "
6431 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6432 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6433 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006434 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006435 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006436
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006437 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006438 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6439 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
6440 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6441 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6442 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006443 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006444
6445 mLock.unlock();
6446
Prabir Pradhana41d2442023-04-20 21:30:40 +00006447 bool fallback = false;
6448 if (auto fb = mPolicy.dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
6449 event, keyEntry.policyFlags);
6450 fb) {
6451 fallback = true;
6452 event = *fb;
6453 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006454
6455 mLock.lock();
6456
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08006457 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006458 connection->inputState.removeFallbackKey(originalKeyCode);
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006459 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006460 }
6461
6462 // Latch the fallback keycode for this key on an initial down.
6463 // The fallback keycode cannot change at any other point in the lifecycle.
6464 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006465 if (fallback) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006466 *fallbackKeyCode = event.getKeyCode();
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006467 } else {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006468 *fallbackKeyCode = AKEYCODE_UNKNOWN;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006469 }
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006470 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006471 }
6472
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006473 ALOG_ASSERT(fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006474
6475 // Cancel the fallback key if the policy decides not to send it anymore.
6476 // We will continue to dispatch the key to the policy but we will no
6477 // longer dispatch a fallback key to the application.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006478 if (*fallbackKeyCode != AKEYCODE_UNKNOWN &&
6479 (!fallback || *fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006480 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6481 if (fallback) {
6482 ALOGD("Unhandled key event: Policy requested to send key %d"
6483 "as a fallback for %d, but on the DOWN it had requested "
6484 "to send %d instead. Fallback canceled.",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006485 event.getKeyCode(), originalKeyCode, *fallbackKeyCode);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006486 } else {
6487 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6488 "but on the DOWN it had requested to send %d. "
6489 "Fallback canceled.",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006490 originalKeyCode, *fallbackKeyCode);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006491 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006492 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006493
Michael Wrightfb04fd52022-11-24 22:31:11 +00006494 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006495 "canceling fallback, policy no longer desires it");
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006496 options.keyCode = *fallbackKeyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006497 synthesizeCancelationEventsForConnectionLocked(connection, options);
6498
6499 fallback = false;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006500 *fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006501 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006502 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006503 }
6504 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006505
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006506 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6507 {
6508 std::string msg;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006509 const std::map<int32_t, int32_t>& fallbackKeys =
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006510 connection->inputState.getFallbackKeys();
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006511 for (const auto& [key, value] : fallbackKeys) {
6512 msg += StringPrintf(", %d->%d", key, value);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006513 }
6514 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6515 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006516 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006517 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006518
6519 if (fallback) {
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006520 // Return the fallback key that we want dispatched to the channel.
6521 std::unique_ptr<KeyEntry> newEntry =
6522 std::make_unique<KeyEntry>(mIdGenerator.nextId(), keyEntry.injectionState,
6523 event.getEventTime(), event.getDeviceId(),
6524 event.getSource(), event.getDisplayId(),
6525 keyEntry.policyFlags, keyEntry.action,
6526 event.getFlags() | AKEY_EVENT_FLAG_FALLBACK,
6527 *fallbackKeyCode, event.getScanCode(),
6528 event.getMetaState(), event.getRepeatCount(),
6529 event.getDownTime());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006530 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6531 ALOGD("Unhandled key event: Dispatching fallback key. "
6532 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006533 originalKeyCode, *fallbackKeyCode, keyEntry.metaState);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006534 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006535 return newEntry;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006536 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006537 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6538 ALOGD("Unhandled key event: No fallback key.");
6539 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006540
6541 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006542 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006543 }
6544 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006545 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08006546}
6547
Michael Wrightd02c5b62014-02-10 15:10:22 -08006548void InputDispatcher::traceInboundQueueLengthLocked() {
6549 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006550 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006551 }
6552}
6553
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006554void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006555 if (ATRACE_ENABLED()) {
6556 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006557 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6558 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006559 }
6560}
6561
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006562void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006563 if (ATRACE_ENABLED()) {
6564 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006565 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6566 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006567 }
6568}
6569
Siarhei Vishniakou5e20f272023-06-08 17:24:44 -07006570void InputDispatcher::dump(std::string& dump) const {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006571 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006572
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006573 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006574 dumpDispatchStateLocked(dump);
6575
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006576 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006577 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006578 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006579 }
6580}
6581
6582void InputDispatcher::monitor() {
6583 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006584 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006585 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006586 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006587}
6588
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006589/**
6590 * Wake up the dispatcher and wait until it processes all events and commands.
6591 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6592 * this method can be safely called from any thread, as long as you've ensured that
6593 * the work you are interested in completing has already been queued.
6594 */
Siarhei Vishniakoua66d65e2023-06-16 10:32:51 -07006595bool InputDispatcher::waitForIdle() const {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006596 /**
6597 * Timeout should represent the longest possible time that a device might spend processing
6598 * events and commands.
6599 */
6600 constexpr std::chrono::duration TIMEOUT = 100ms;
6601 std::unique_lock lock(mLock);
6602 mLooper->wake();
6603 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6604 return result == std::cv_status::no_timeout;
6605}
6606
Vishnu Naire798b472020-07-23 13:52:21 -07006607/**
6608 * Sets focus to the window identified by the token. This must be called
6609 * after updating any input window handles.
6610 *
6611 * Params:
6612 * request.token - input channel token used to identify the window that should gain focus.
6613 * request.focusedToken - the token that the caller expects currently to be focused. If the
6614 * specified token does not match the currently focused window, this request will be dropped.
6615 * If the specified focused token matches the currently focused window, the call will succeed.
6616 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6617 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6618 * when requesting the focus change. This determines which request gets
6619 * precedence if there is a focus change request from another source such as pointer down.
6620 */
Vishnu Nair958da932020-08-21 17:12:37 -07006621void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6622 { // acquire lock
6623 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006624 std::optional<FocusResolver::FocusChanges> changes =
6625 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6626 if (changes) {
6627 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006628 }
6629 } // release lock
6630 // Wake up poll loop since it may need to make new input dispatching choices.
6631 mLooper->wake();
6632}
6633
Vishnu Nairc519ff72021-01-21 08:23:08 -08006634void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6635 if (changes.oldFocus) {
6636 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006637 if (focusedInputChannel) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00006638 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006639 "focus left window");
6640 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Harry Cutts33476232023-01-30 19:57:29 +00006641 enqueueFocusEventLocked(changes.oldFocus, /*hasFocus=*/false, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006642 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006643 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006644 if (changes.newFocus) {
Siarhei Vishniakouc033dfb2023-10-03 10:45:16 -07006645 resetNoFocusedWindowTimeoutLocked();
Harry Cutts33476232023-01-30 19:57:29 +00006646 enqueueFocusEventLocked(changes.newFocus, /*hasFocus=*/true, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006647 }
6648
Prabir Pradhan99987712020-11-10 18:43:05 -08006649 // If a window has pointer capture, then it must have focus. We need to ensure that this
6650 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6651 // If the window loses focus before it loses pointer capture, then the window can be in a state
6652 // where it has pointer capture but not focus, violating the contract. Therefore we must
6653 // dispatch the pointer capture event before the focus event. Since focus events are added to
6654 // the front of the queue (above), we add the pointer capture event to the front of the queue
6655 // after the focus events are added. This ensures the pointer capture event ends up at the
6656 // front.
6657 disablePointerCaptureForcedLocked();
6658
Vishnu Nairc519ff72021-01-21 08:23:08 -08006659 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006660 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006661 }
6662}
Vishnu Nair958da932020-08-21 17:12:37 -07006663
Prabir Pradhan99987712020-11-10 18:43:05 -08006664void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006665 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006666 return;
6667 }
6668
6669 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6670
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006671 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006672 setPointerCaptureLocked(false);
6673 }
6674
6675 if (!mWindowTokenWithPointerCapture) {
6676 // No need to send capture changes because no window has capture.
6677 return;
6678 }
6679
6680 if (mPendingEvent != nullptr) {
6681 // Move the pending event to the front of the queue. This will give the chance
6682 // for the pending event to be dropped if it is a captured event.
6683 mInboundQueue.push_front(mPendingEvent);
6684 mPendingEvent = nullptr;
6685 }
6686
6687 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006688 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006689 mInboundQueue.push_front(std::move(entry));
6690}
6691
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006692void InputDispatcher::setPointerCaptureLocked(bool enable) {
6693 mCurrentPointerCaptureRequest.enable = enable;
6694 mCurrentPointerCaptureRequest.seq++;
6695 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006696 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006697 mPolicy.setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006698 };
6699 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006700}
6701
Vishnu Nair599f1412021-06-21 10:39:58 -07006702void InputDispatcher::displayRemoved(int32_t displayId) {
6703 { // acquire lock
6704 std::scoped_lock _l(mLock);
6705 // Set an empty list to remove all handles from the specific display.
Harry Cutts101ee9b2023-07-06 18:04:14 +00006706 setInputWindowsLocked(/*windowInfoHandles=*/{}, displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006707 setFocusedApplicationLocked(displayId, nullptr);
6708 // Call focus resolver to clean up stale requests. This must be called after input windows
6709 // have been removed for the removed display.
6710 mFocusResolver.displayRemoved(displayId);
Christine Franksb768bb42021-11-29 12:11:31 -08006711 // Reset pointer capture eligibility, regardless of previous state.
6712 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
Antonio Kantek15beb512022-06-13 22:35:41 +00006713 // Remove the associated touch mode state.
6714 mTouchModePerDisplay.erase(displayId);
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07006715 mVerifiersByDisplay.erase(displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006716 } // release lock
6717
6718 // Wake up poll loop since it may need to make new input dispatching choices.
6719 mLooper->wake();
6720}
6721
Patrick Williamsd828f302023-04-28 17:52:08 -05006722void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update) {
chaviw15fab6f2021-06-07 14:15:52 -05006723 // The listener sends the windows as a flattened array. Separate the windows by display for
6724 // more convenient parsing.
6725 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
Patrick Williamsd828f302023-04-28 17:52:08 -05006726 for (const auto& info : update.windowInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006727 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07006728 handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
chaviw15fab6f2021-06-07 14:15:52 -05006729 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006730
6731 { // acquire lock
6732 std::scoped_lock _l(mLock);
Prabir Pradhan814fe082022-07-22 20:22:18 +00006733
6734 // Ensure that we have an entry created for all existing displays so that if a displayId has
6735 // no windows, we can tell that the windows were removed from the display.
6736 for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
6737 handlesPerDisplay[displayId];
6738 }
6739
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006740 mDisplayInfos.clear();
Patrick Williamsd828f302023-04-28 17:52:08 -05006741 for (const auto& displayInfo : update.displayInfos) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006742 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6743 }
6744
6745 for (const auto& [displayId, handles] : handlesPerDisplay) {
6746 setInputWindowsLocked(handles, displayId);
6747 }
Patrick Williams9464b2c2023-05-23 11:22:04 -05006748
6749 if (update.vsyncId < mWindowInfosVsyncId) {
6750 ALOGE("Received out of order window infos update. Last update vsync id: %" PRId64
6751 ", current update vsync id: %" PRId64,
6752 mWindowInfosVsyncId, update.vsyncId);
6753 }
6754 mWindowInfosVsyncId = update.vsyncId;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006755 }
6756 // Wake up poll loop since it may need to make new input dispatching choices.
6757 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006758}
6759
Vishnu Nair062a8672021-09-03 16:07:44 -07006760bool InputDispatcher::shouldDropInput(
6761 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006762 if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
6763 (windowHandle->getInfo()->inputConfig.test(
6764 WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
Vishnu Nair062a8672021-09-03 16:07:44 -07006765 isWindowObscuredLocked(windowHandle))) {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006766 ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on "
6767 "display %" PRId32 ".",
Vishnu Nair062a8672021-09-03 16:07:44 -07006768 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006769 windowHandle->getInfo()->inputConfig.string().c_str(),
Vishnu Nair062a8672021-09-03 16:07:44 -07006770 windowHandle->getInfo()->displayId);
6771 return true;
6772 }
6773 return false;
6774}
6775
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006776void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
Patrick Williamsd828f302023-04-28 17:52:08 -05006777 const gui::WindowInfosUpdate& update) {
6778 mDispatcher.onWindowInfosChanged(update);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006779}
6780
Arthur Hungdfd528e2021-12-08 13:23:04 +00006781void InputDispatcher::cancelCurrentTouch() {
6782 {
6783 std::scoped_lock _l(mLock);
6784 ALOGD("Canceling all ongoing pointer gestures on all displays.");
Michael Wrightfb04fd52022-11-24 22:31:11 +00006785 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Arthur Hungdfd528e2021-12-08 13:23:04 +00006786 "cancel current touch");
6787 synthesizeCancelationEventsForAllConnectionsLocked(options);
6788
6789 mTouchStatesByDisplay.clear();
Arthur Hungdfd528e2021-12-08 13:23:04 +00006790 }
6791 // Wake up poll loop since there might be work to do.
6792 mLooper->wake();
6793}
6794
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08006795void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout) {
6796 std::scoped_lock _l(mLock);
6797 mMonitorDispatchingTimeout = timeout;
6798}
6799
Arthur Hungc539dbb2022-12-08 07:45:36 +00006800void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
6801 const sp<WindowInfoHandle>& oldWindowHandle,
6802 const sp<WindowInfoHandle>& newWindowHandle,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006803 TouchState& state, int32_t deviceId,
6804 const PointerProperties& pointerProperties,
Siarhei Vishniakoubf880522023-05-01 11:03:22 -07006805 std::vector<InputTarget>& targets) const {
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006806 std::vector<PointerProperties> pointers{pointerProperties};
Arthur Hungc539dbb2022-12-08 07:45:36 +00006807 const bool oldHasWallpaper = oldWindowHandle->getInfo()->inputConfig.test(
6808 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6809 const bool newHasWallpaper = targetFlags.test(InputTarget::Flags::FOREGROUND) &&
6810 newWindowHandle->getInfo()->inputConfig.test(
6811 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6812 const sp<WindowInfoHandle> oldWallpaper =
6813 oldHasWallpaper ? state.getWallpaperWindow() : nullptr;
6814 const sp<WindowInfoHandle> newWallpaper =
6815 newHasWallpaper ? findWallpaperWindowBelow(newWindowHandle) : nullptr;
6816 if (oldWallpaper == newWallpaper) {
6817 return;
6818 }
6819
6820 if (oldWallpaper != nullptr) {
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08006821 const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper);
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006822 addPointerWindowTargetLocked(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006823 oldTouchedWindow.targetFlags, getPointerIds(pointers),
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006824 oldTouchedWindow.getDownTimeInTarget(deviceId), targets);
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006825 state.removeTouchingPointerFromWindow(deviceId, pointerProperties.id, oldWallpaper);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006826 }
6827
6828 if (newWallpaper != nullptr) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006829 state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::SLIPPERY_ENTER,
6830 InputTarget::Flags::WINDOW_IS_OBSCURED |
Arthur Hungc539dbb2022-12-08 07:45:36 +00006831 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006832 deviceId, pointers);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006833 }
6834}
6835
6836void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags,
6837 ftl::Flags<InputTarget::Flags> newTargetFlags,
6838 const sp<WindowInfoHandle> fromWindowHandle,
6839 const sp<WindowInfoHandle> toWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006840 TouchState& state, int32_t deviceId,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006841 const std::vector<PointerProperties>& pointers) {
Arthur Hungc539dbb2022-12-08 07:45:36 +00006842 const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
6843 fromWindowHandle->getInfo()->inputConfig.test(
6844 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6845 const bool newHasWallpaper = newTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
6846 toWindowHandle->getInfo()->inputConfig.test(
6847 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6848
6849 const sp<WindowInfoHandle> oldWallpaper =
6850 oldHasWallpaper ? state.getWallpaperWindow() : nullptr;
6851 const sp<WindowInfoHandle> newWallpaper =
6852 newHasWallpaper ? findWallpaperWindowBelow(toWindowHandle) : nullptr;
6853 if (oldWallpaper == newWallpaper) {
6854 return;
6855 }
6856
6857 if (oldWallpaper != nullptr) {
6858 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6859 "transferring touch focus to another window");
6860 state.removeWindowByToken(oldWallpaper->getToken());
6861 synthesizeCancelationEventsForWindowLocked(oldWallpaper, options);
6862 }
6863
6864 if (newWallpaper != nullptr) {
6865 nsecs_t downTimeInTarget = now();
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006866 ftl::Flags<InputTarget::Flags> wallpaperFlags = oldTargetFlags & InputTarget::Flags::SPLIT;
Arthur Hungc539dbb2022-12-08 07:45:36 +00006867 wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED |
6868 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006869 state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006870 deviceId, pointers, downTimeInTarget);
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006871 std::shared_ptr<Connection> wallpaperConnection =
6872 getConnectionLocked(newWallpaper->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00006873 if (wallpaperConnection != nullptr) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006874 std::shared_ptr<Connection> toConnection =
6875 getConnectionLocked(toWindowHandle->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00006876 toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState);
6877 synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, wallpaperConnection,
6878 wallpaperFlags);
6879 }
6880 }
6881}
6882
6883sp<WindowInfoHandle> InputDispatcher::findWallpaperWindowBelow(
6884 const sp<WindowInfoHandle>& windowHandle) const {
6885 const std::vector<sp<WindowInfoHandle>>& windowHandles =
6886 getWindowHandlesLocked(windowHandle->getInfo()->displayId);
6887 bool foundWindow = false;
6888 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
6889 if (!foundWindow && otherHandle != windowHandle) {
6890 continue;
6891 }
6892 if (windowHandle == otherHandle) {
6893 foundWindow = true;
6894 continue;
6895 }
6896
6897 if (otherHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::IS_WALLPAPER)) {
6898 return otherHandle;
6899 }
6900 }
6901 return nullptr;
6902}
6903
Siarhei Vishniakoufa2a0492023-11-14 13:13:18 -08006904void InputDispatcher::setKeyRepeatConfiguration(std::chrono::nanoseconds timeout,
6905 std::chrono::nanoseconds delay) {
Nergi Rahardi730cf3c2023-04-13 12:41:17 +09006906 std::scoped_lock _l(mLock);
6907
Siarhei Vishniakoufa2a0492023-11-14 13:13:18 -08006908 mConfig.keyRepeatTimeout = timeout.count();
6909 mConfig.keyRepeatDelay = delay.count();
Nergi Rahardi730cf3c2023-04-13 12:41:17 +09006910}
6911
Prabir Pradhan64f21d22023-11-28 21:19:42 +00006912bool InputDispatcher::isPointerInWindow(const sp<android::IBinder>& token, int32_t displayId,
6913 DeviceId deviceId, int32_t pointerId) {
6914 std::scoped_lock _l(mLock);
6915 auto touchStateIt = mTouchStatesByDisplay.find(displayId);
6916 if (touchStateIt == mTouchStatesByDisplay.end()) {
6917 return false;
6918 }
6919 for (const TouchedWindow& window : touchStateIt->second.windows) {
6920 if (window.windowHandle->getToken() == token &&
6921 (window.hasTouchingPointer(deviceId, pointerId) ||
6922 window.hasHoveringPointer(deviceId, pointerId))) {
6923 return true;
6924 }
6925 }
6926 return false;
6927}
6928
Garfield Tane84e6f92019-08-29 17:28:41 -07006929} // namespace android::inputdispatcher