blob: 4aac377b42368c5d58b25d349c783696286a12dd [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>
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080023#include <android-base/properties.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080024#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050025#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070026#include <binder/Binder.h>
Dominik Laskowski75788452021-02-09 18:51:25 -080027#include <ftl/enum.h>
Siarhei Vishniakou31977182022-09-30 08:51:23 -070028#if defined(__ANDROID__)
chaviw15fab6f2021-06-07 14:15:52 -050029#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou31977182022-09-30 08:51:23 -070030#endif
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080031#include <input/InputDevice.h>
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -080032#include <input/PrintTools.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070033#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010034#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070035#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080036
Michael Wright44753b12020-07-08 13:48:11 +010037#include <cerrno>
38#include <cinttypes>
39#include <climits>
40#include <cstddef>
41#include <ctime>
42#include <queue>
43#include <sstream>
44
45#include "Connection.h"
Arthur Hung1a1007b2022-05-11 07:15:01 +000046#include "DebugConfig.h"
Chris Yef59a2f42020-10-16 12:55:26 -070047#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010048
Michael Wrightd02c5b62014-02-10 15:10:22 -080049#define INDENT " "
50#define INDENT2 " "
51#define INDENT3 " "
52#define INDENT4 " "
53
Siarhei Vishniakou253f4642022-11-09 13:42:06 -080054using namespace android::ftl::flag_operators;
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080055using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000056using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080057using android::base::StringPrintf;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -070058using android::gui::DisplayInfo;
chaviw98318de2021-05-19 16:45:23 -050059using android::gui::FocusRequest;
60using android::gui::TouchOcclusionMode;
61using android::gui::WindowInfo;
62using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080063using android::os::InputEventInjectionResult;
64using android::os::InputEventInjectionSync;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080065
Garfield Tane84e6f92019-08-29 17:28:41 -070066namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080067
Prabir Pradhancef936d2021-07-21 16:17:52 +000068namespace {
Prabir Pradhancef936d2021-07-21 16:17:52 +000069// Temporarily releases a held mutex for the lifetime of the instance.
70// Named to match std::scoped_lock
71class scoped_unlock {
72public:
73 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
74 ~scoped_unlock() { mMutex.lock(); }
75
76private:
77 std::mutex& mMutex;
78};
79
Michael Wrightd02c5b62014-02-10 15:10:22 -080080// Default input dispatching timeout if there is no focused application or paused window
81// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080082const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
83 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
84 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -080085
86// Amount of time to allow for all pending events to be processed when an app switch
87// key is on the way. This is used to preempt input dispatch and drop input events
88// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000089constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080090
Siarhei Vishniakou289e9242022-02-15 14:50:16 -080091const std::chrono::duration STALE_EVENT_TIMEOUT = std::chrono::seconds(10) * HwTimeoutMultiplier();
Michael Wrightd02c5b62014-02-10 15:10:22 -080092
Michael Wrightd02c5b62014-02-10 15:10:22 -080093// 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 +000094constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
95
96// Log a warning when an interception call takes longer than this to process.
97constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -080098
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -070099// Additional key latency in case a connection is still processing some motion events.
100// This will help with the case when a user touched a button that opens a new window,
101// and gives us the chance to dispatch the key to this new window.
102constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
103
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000105constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
106
Antonio Kantekea47acb2021-12-23 12:41:25 -0800107// Event log tags. See EventLogTags.logtags for reference.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000108constexpr int LOGTAG_INPUT_INTERACTION = 62000;
109constexpr int LOGTAG_INPUT_FOCUS = 62001;
Arthur Hungb3307ee2021-10-14 10:57:37 +0000110constexpr int LOGTAG_INPUT_CANCEL = 62003;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000111
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000112inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800113 return systemTime(SYSTEM_TIME_MONOTONIC);
114}
115
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000116inline const char* toString(bool value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800117 return value ? "true" : "false";
118}
119
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000120inline const std::string toString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000121 if (binder == nullptr) {
122 return "<null>";
123 }
124 return StringPrintf("%p", binder.get());
125}
126
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000127inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700128 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
129 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800130}
131
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000132bool isValidKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800133 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700134 case AKEY_EVENT_ACTION_DOWN:
135 case AKEY_EVENT_ACTION_UP:
136 return true;
137 default:
138 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800139 }
140}
141
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000142bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700143 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800144 ALOGE("Key event has invalid action code 0x%x", action);
145 return false;
146 }
147 return true;
148}
149
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000150bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800151 switch (MotionEvent::getActionMasked(action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700152 case AMOTION_EVENT_ACTION_DOWN:
153 case AMOTION_EVENT_ACTION_UP:
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800154 return pointerCount == 1;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700155 case AMOTION_EVENT_ACTION_MOVE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700156 case AMOTION_EVENT_ACTION_HOVER_ENTER:
157 case AMOTION_EVENT_ACTION_HOVER_MOVE:
158 case AMOTION_EVENT_ACTION_HOVER_EXIT:
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800159 return pointerCount >= 1;
160 case AMOTION_EVENT_ACTION_CANCEL:
161 case AMOTION_EVENT_ACTION_OUTSIDE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700162 case AMOTION_EVENT_ACTION_SCROLL:
163 return true;
164 case AMOTION_EVENT_ACTION_POINTER_DOWN:
165 case AMOTION_EVENT_ACTION_POINTER_UP: {
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800166 const int32_t index = MotionEvent::getActionIndex(action);
167 return index >= 0 && index < pointerCount && pointerCount > 1;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700168 }
169 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
170 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
171 return actionButton != 0;
172 default:
173 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800174 }
175}
176
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000177int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500178 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
179}
180
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000181bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
182 const PointerProperties* pointerProperties) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700183 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800184 ALOGE("Motion event has invalid action code 0x%x", action);
185 return false;
186 }
187 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Siarhei Vishniakou01747382022-01-20 13:23:27 -0800188 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %zu.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700189 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800190 return false;
191 }
192 BitSet32 pointerIdBits;
193 for (size_t i = 0; i < pointerCount; i++) {
194 int32_t id = pointerProperties[i].id;
195 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700196 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
197 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800198 return false;
199 }
200 if (pointerIdBits.hasBit(id)) {
201 ALOGE("Motion event has duplicate pointer id %d", id);
202 return false;
203 }
204 pointerIdBits.markBit(id);
205 }
206 return true;
207}
208
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000209std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800210 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000211 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800212 }
213
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000214 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800215 bool first = true;
216 Region::const_iterator cur = region.begin();
217 Region::const_iterator const tail = region.end();
218 while (cur != tail) {
219 if (first) {
220 first = false;
221 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800222 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800223 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800224 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800225 cur++;
226 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000227 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800228}
229
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000230std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500231 constexpr size_t maxEntries = 50; // max events to print
232 constexpr size_t skipBegin = maxEntries / 2;
233 const size_t skipEnd = queue.size() - maxEntries / 2;
234 // skip from maxEntries / 2 ... size() - maxEntries/2
235 // only print from 0 .. skipBegin and then from skipEnd .. size()
236
237 std::string dump;
238 for (size_t i = 0; i < queue.size(); i++) {
239 const DispatchEntry& entry = *queue[i];
240 if (i >= skipBegin && i < skipEnd) {
241 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
242 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
243 continue;
244 }
245 dump.append(INDENT4);
246 dump += entry.eventEntry->getDescription();
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800247 dump += StringPrintf(", seq=%" PRIu32 ", targetFlags=%s, resolvedAction=%d, age=%" PRId64
248 "ms",
249 entry.seq, entry.targetFlags.string().c_str(), entry.resolvedAction,
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500250 ns2ms(currentTime - entry.eventEntry->eventTime));
251 if (entry.deliveryTime != 0) {
252 // This entry was delivered, so add information on how long we've been waiting
253 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
254 }
255 dump.append("\n");
256 }
257 return dump;
258}
259
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700260/**
261 * Find the entry in std::unordered_map by key, and return it.
262 * If the entry is not found, return a default constructed entry.
263 *
264 * Useful when the entries are vectors, since an empty vector will be returned
265 * if the entry is not found.
266 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
267 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700268template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000269V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700270 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700271 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800272}
273
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000274bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700275 if (first == second) {
276 return true;
277 }
278
279 if (first == nullptr || second == nullptr) {
280 return false;
281 }
282
283 return first->getToken() == second->getToken();
284}
285
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000286bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000287 if (first == nullptr || second == nullptr) {
288 return false;
289 }
290 return first->applicationInfo.token != nullptr &&
291 first->applicationInfo.token == second->applicationInfo.token;
292}
293
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800294std::unique_ptr<DispatchEntry> createDispatchEntry(
295 const InputTarget& inputTarget, std::shared_ptr<EventEntry> eventEntry,
296 ftl::Flags<InputTarget::Flags> inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700297 if (inputTarget.useDefaultPointerTransform()) {
298 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700299 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700300 inputTarget.displayTransform,
301 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000302 }
303
304 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
305 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
306
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700307 std::vector<PointerCoords> pointerCoords;
308 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000309
310 // Use the first pointer information to normalize all other pointers. This could be any pointer
311 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700312 // uses the transform for the normalized pointer.
313 const ui::Transform& firstPointerTransform =
314 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
315 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000316
317 // Iterate through all pointers in the event to normalize against the first.
318 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
319 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
320 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700321 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000322
323 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700324 // First, apply the current pointer's transform to update the coordinates into
325 // window space.
326 pointerCoords[pointerIndex].transform(currTransform);
327 // Next, apply the inverse transform of the normalized coordinates so the
328 // current coordinates are transformed into the normalized coordinate space.
329 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000330 }
331
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700332 std::unique_ptr<MotionEntry> combinedMotionEntry =
333 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
334 motionEntry.deviceId, motionEntry.source,
335 motionEntry.displayId, motionEntry.policyFlags,
336 motionEntry.action, motionEntry.actionButton,
337 motionEntry.flags, motionEntry.metaState,
338 motionEntry.buttonState, motionEntry.classification,
339 motionEntry.edgeFlags, motionEntry.xPrecision,
340 motionEntry.yPrecision, motionEntry.xCursorPosition,
341 motionEntry.yCursorPosition, motionEntry.downTime,
342 motionEntry.pointerCount, motionEntry.pointerProperties,
Prabir Pradhan5beda762021-12-10 09:30:08 +0000343 pointerCoords.data());
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000344
345 if (motionEntry.injectionState) {
346 combinedMotionEntry->injectionState = motionEntry.injectionState;
347 combinedMotionEntry->injectionState->refCount += 1;
348 }
349
350 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700351 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700352 firstPointerTransform, inputTarget.displayTransform,
353 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000354 return dispatchEntry;
355}
356
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000357status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
358 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700359 std::unique_ptr<InputChannel> uniqueServerChannel;
360 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
361
362 serverChannel = std::move(uniqueServerChannel);
363 return result;
364}
365
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500366template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000367bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500368 if (lhs == nullptr && rhs == nullptr) {
369 return true;
370 }
371 if (lhs == nullptr || rhs == nullptr) {
372 return false;
373 }
374 return *lhs == *rhs;
375}
376
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000377KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000378 KeyEvent event;
379 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
380 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
381 entry.repeatCount, entry.downTime, entry.eventTime);
382 return event;
383}
384
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000385bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000386 // Do not keep track of gesture monitors. They receive every event and would disproportionately
387 // affect the statistics.
388 if (connection.monitor) {
389 return false;
390 }
391 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
392 if (!connection.responsive) {
393 return false;
394 }
395 return true;
396}
397
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000398bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000399 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
400 const int32_t& inputEventId = eventEntry.id;
401 if (inputEventId != dispatchEntry.resolvedEventId) {
402 // Event was transmuted
403 return false;
404 }
405 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
406 return false;
407 }
408 // Only track latency for events that originated from hardware
409 if (eventEntry.isSynthesized()) {
410 return false;
411 }
412 const EventEntry::Type& inputEventEntryType = eventEntry.type;
413 if (inputEventEntryType == EventEntry::Type::KEY) {
414 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
415 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
416 return false;
417 }
418 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
419 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
420 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
421 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
422 return false;
423 }
424 } else {
425 // Not a key or a motion
426 return false;
427 }
428 if (!shouldReportMetricsForConnection(connection)) {
429 return false;
430 }
431 return true;
432}
433
Prabir Pradhancef936d2021-07-21 16:17:52 +0000434/**
435 * Connection is responsive if it has no events in the waitQueue that are older than the
436 * current time.
437 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000438bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000439 const nsecs_t currentTime = now();
440 for (const DispatchEntry* entry : connection.waitQueue) {
441 if (entry->timeoutTime < currentTime) {
442 return false;
443 }
444 }
445 return true;
446}
447
Antonio Kantekf16f2832021-09-28 04:39:20 +0000448// Returns true if the event type passed as argument represents a user activity.
449bool isUserActivityEvent(const EventEntry& eventEntry) {
450 switch (eventEntry.type) {
451 case EventEntry::Type::FOCUS:
452 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
453 case EventEntry::Type::DRAG:
454 case EventEntry::Type::TOUCH_MODE_CHANGED:
455 case EventEntry::Type::SENSOR:
456 case EventEntry::Type::CONFIGURATION_CHANGED:
457 return false;
458 case EventEntry::Type::DEVICE_RESET:
459 case EventEntry::Type::KEY:
460 case EventEntry::Type::MOTION:
461 return true;
462 }
463}
464
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800465// Returns true if the given window can accept pointer events at the given display location.
Prabir Pradhand65552b2021-10-07 11:23:50 -0700466bool windowAcceptsTouchAt(const WindowInfo& windowInfo, int32_t displayId, int32_t x, int32_t y,
467 bool isStylus) {
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800468 const auto inputConfig = windowInfo.inputConfig;
469 if (windowInfo.displayId != displayId ||
470 inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800471 return false;
472 }
Prabir Pradhand65552b2021-10-07 11:23:50 -0700473 const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800474 if (inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800475 return false;
476 }
Prabir Pradhan06349042022-02-04 09:19:17 -0800477 if (!windowInfo.touchableRegionContainsPoint(x, y)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800478 return false;
479 }
480 return true;
481}
482
Prabir Pradhand65552b2021-10-07 11:23:50 -0700483bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
484 return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
Prabir Pradhane5626962022-10-27 20:30:53 +0000485 isStylusToolType(entry.pointerProperties[pointerIndex].toolType);
Prabir Pradhand65552b2021-10-07 11:23:50 -0700486}
487
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800488// Determines if the given window can be targeted as InputTarget::Flags::FOREGROUND.
Prabir Pradhan6dfbf262022-03-14 15:24:30 +0000489// Foreground events are only sent to "foreground targetable" windows, but not all gestures sent to
490// such window are necessarily targeted with the flag. For example, an event with ACTION_OUTSIDE can
491// be sent to such a window, but it is not a foreground event and doesn't use
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800492// InputTarget::Flags::FOREGROUND.
Prabir Pradhan6dfbf262022-03-14 15:24:30 +0000493bool canReceiveForegroundTouches(const WindowInfo& info) {
494 // A non-touchable window can still receive touch events (e.g. in the case of
495 // STYLUS_INTERCEPTOR), so prevent such windows from receiving foreground events for touches.
496 return !info.inputConfig.test(gui::WindowInfo::InputConfig::NOT_TOUCHABLE) && !info.isSpy();
497}
498
Antonio Kantek48710e42022-03-24 14:19:30 -0700499bool isWindowOwnedBy(const sp<WindowInfoHandle>& windowHandle, int32_t pid, int32_t uid) {
500 if (windowHandle == nullptr) {
501 return false;
502 }
503 const WindowInfo* windowInfo = windowHandle->getInfo();
504 if (pid == windowInfo->ownerPid && uid == windowInfo->ownerUid) {
505 return true;
506 }
507 return false;
508}
509
Prabir Pradhan5735a322022-04-11 17:23:34 +0000510// Checks targeted injection using the window's owner's uid.
511// Returns an empty string if an entry can be sent to the given window, or an error message if the
512// entry is a targeted injection whose uid target doesn't match the window owner.
513std::optional<std::string> verifyTargetedInjection(const sp<WindowInfoHandle>& window,
514 const EventEntry& entry) {
515 if (entry.injectionState == nullptr || !entry.injectionState->targetUid) {
516 // The event was not injected, or the injected event does not target a window.
517 return {};
518 }
519 const int32_t uid = *entry.injectionState->targetUid;
520 if (window == nullptr) {
521 return StringPrintf("No valid window target for injection into uid %d.", uid);
522 }
523 if (entry.injectionState->targetUid != window->getInfo()->ownerUid) {
524 return StringPrintf("Injected event targeted at uid %d would be dispatched to window '%s' "
525 "owned by uid %d.",
526 uid, window->getName().c_str(), window->getInfo()->ownerUid);
527 }
528 return {};
529}
530
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700531Point resolveTouchedPosition(const MotionEntry& entry) {
532 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
533 // Always dispatch mouse events to cursor position.
534 if (isFromMouse) {
535 return Point(static_cast<int32_t>(entry.xCursorPosition),
536 static_cast<int32_t>(entry.yCursorPosition));
537 }
538
539 const int32_t pointerIndex = getMotionEventActionPointerIndex(entry.action);
540 return Point(static_cast<int32_t>(
541 entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X)),
542 static_cast<int32_t>(
543 entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y)));
544}
545
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -0700546std::optional<nsecs_t> getDownTime(const EventEntry& eventEntry) {
547 if (eventEntry.type == EventEntry::Type::KEY) {
548 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
549 return keyEntry.downTime;
550 } else if (eventEntry.type == EventEntry::Type::MOTION) {
551 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
552 return motionEntry.downTime;
553 }
554 return std::nullopt;
555}
556
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000557} // namespace
558
Michael Wrightd02c5b62014-02-10 15:10:22 -0800559// --- InputDispatcher ---
560
Garfield Tan00f511d2019-06-12 16:55:40 -0700561InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800562 : InputDispatcher(policy, STALE_EVENT_TIMEOUT) {}
563
564InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy,
565 std::chrono::nanoseconds staleEventTimeout)
Garfield Tan00f511d2019-06-12 16:55:40 -0700566 : mPolicy(policy),
567 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700568 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800569 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700570 mAppSwitchSawKeyDown(false),
Colin Cross5b799302022-10-18 21:52:41 -0700571 mAppSwitchDueTime(LLONG_MAX),
Garfield Tan00f511d2019-06-12 16:55:40 -0700572 mNextUnblockedEvent(nullptr),
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800573 mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
Garfield Tan00f511d2019-06-12 16:55:40 -0700574 mDispatchEnabled(false),
575 mDispatchFrozen(false),
576 mInputFilterEnabled(false),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100577 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000578 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800579 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800580 mStaleEventTimeout(staleEventTimeout),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000581 mLatencyAggregator(),
Antonio Kantek15beb512022-06-13 22:35:41 +0000582 mLatencyTracker(&mLatencyAggregator) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700583 mLooper = sp<Looper>::make(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800584 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800585
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700586 mWindowInfoListener = sp<DispatcherWindowListener>::make(*this);
Siarhei Vishniakou31977182022-09-30 08:51:23 -0700587#if defined(__ANDROID__)
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700588 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
Siarhei Vishniakou31977182022-09-30 08:51:23 -0700589#endif
Yi Kong9b14ac62018-07-17 13:48:38 -0700590 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800591 policy->getDispatcherConfiguration(&mConfig);
592}
593
594InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000595 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800596
Prabir Pradhancef936d2021-07-21 16:17:52 +0000597 resetKeyRepeatLocked();
598 releasePendingEventLocked();
599 drainInboundQueueLocked();
600 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800601
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000602 while (!mConnectionsByToken.empty()) {
603 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000604 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
605 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800606 }
607}
608
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700609status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700610 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700611 return ALREADY_EXISTS;
612 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700613 mThread = std::make_unique<InputThread>(
614 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
615 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700616}
617
618status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700619 if (mThread && mThread->isCallingThread()) {
620 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700621 return INVALID_OPERATION;
622 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700623 mThread.reset();
624 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700625}
626
Michael Wrightd02c5b62014-02-10 15:10:22 -0800627void InputDispatcher::dispatchOnce() {
Colin Cross5b799302022-10-18 21:52:41 -0700628 nsecs_t nextWakeupTime = LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800629 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800630 std::scoped_lock _l(mLock);
631 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800632
633 // Run a dispatch loop if there are no pending commands.
634 // The dispatch loop might enqueue commands to run afterwards.
635 if (!haveCommandsLocked()) {
636 dispatchOnceInnerLocked(&nextWakeupTime);
637 }
638
639 // Run all pending commands if there are any.
640 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000641 if (runCommandsLockedInterruptable()) {
Colin Cross5b799302022-10-18 21:52:41 -0700642 nextWakeupTime = LLONG_MIN;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800643 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800644
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700645 // If we are still waiting for ack on some events,
646 // we might have to wake up earlier to check if an app is anr'ing.
647 const nsecs_t nextAnrCheck = processAnrsLocked();
648 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
649
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800650 // We are about to enter an infinitely long sleep, because we have no commands or
651 // pending or queued events
Colin Cross5b799302022-10-18 21:52:41 -0700652 if (nextWakeupTime == LLONG_MAX) {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800653 mDispatcherEnteredIdle.notify_all();
654 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800655 } // release lock
656
657 // Wait for callback or timeout or wake. (make sure we round up, not down)
658 nsecs_t currentTime = now();
659 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
660 mLooper->pollOnce(timeoutMillis);
661}
662
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700663/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500664 * Raise ANR if there is no focused window.
665 * Before the ANR is raised, do a final state check:
666 * 1. The currently focused application must be the same one we are waiting for.
667 * 2. Ensure we still don't have a focused window.
668 */
669void InputDispatcher::processNoFocusedWindowAnrLocked() {
670 // Check if the application that we are waiting for is still focused.
671 std::shared_ptr<InputApplicationHandle> focusedApplication =
672 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
673 if (focusedApplication == nullptr ||
674 focusedApplication->getApplicationToken() !=
675 mAwaitedFocusedApplication->getApplicationToken()) {
676 // Unexpected because we should have reset the ANR timer when focused application changed
677 ALOGE("Waited for a focused window, but focused application has already changed to %s",
678 focusedApplication->getName().c_str());
679 return; // The focused application has changed.
680 }
681
chaviw98318de2021-05-19 16:45:23 -0500682 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500683 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
684 if (focusedWindowHandle != nullptr) {
685 return; // We now have a focused window. No need for ANR.
686 }
687 onAnrLocked(mAwaitedFocusedApplication);
688}
689
690/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700691 * Check if any of the connections' wait queues have events that are too old.
692 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
693 * Return the time at which we should wake up next.
694 */
695nsecs_t InputDispatcher::processAnrsLocked() {
696 const nsecs_t currentTime = now();
Colin Cross5b799302022-10-18 21:52:41 -0700697 nsecs_t nextAnrCheck = LLONG_MAX;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700698 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
699 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
700 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500701 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700702 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500703 mNoFocusedWindowTimeoutTime = std::nullopt;
Colin Cross5b799302022-10-18 21:52:41 -0700704 return LLONG_MIN;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700705 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500706 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700707 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
708 }
709 }
710
711 // Check if any connection ANRs are due
712 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
713 if (currentTime < nextAnrCheck) { // most likely scenario
714 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
715 }
716
717 // If we reached here, we have an unresponsive connection.
718 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
719 if (connection == nullptr) {
720 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
721 return nextAnrCheck;
722 }
723 connection->responsive = false;
724 // Stop waking up for this unresponsive connection
725 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000726 onAnrLocked(connection);
Colin Cross5b799302022-10-18 21:52:41 -0700727 return LLONG_MIN;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700728}
729
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800730std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(
731 const sp<Connection>& connection) {
732 if (connection->monitor) {
733 return mMonitorDispatchingTimeout;
734 }
735 const sp<WindowInfoHandle> window =
736 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700737 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500738 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700739 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500740 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700741}
742
Michael Wrightd02c5b62014-02-10 15:10:22 -0800743void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
744 nsecs_t currentTime = now();
745
Jeff Browndc5992e2014-04-11 01:27:26 -0700746 // Reset the key repeat timer whenever normal dispatch is suspended while the
747 // device is in a non-interactive state. This is to ensure that we abort a key
748 // repeat if the device is just coming out of sleep.
749 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800750 resetKeyRepeatLocked();
751 }
752
753 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
754 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100755 if (DEBUG_FOCUS) {
756 ALOGD("Dispatch frozen. Waiting some more.");
757 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800758 return;
759 }
760
761 // Optimize latency of app switches.
762 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
763 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
764 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
765 if (mAppSwitchDueTime < *nextWakeupTime) {
766 *nextWakeupTime = mAppSwitchDueTime;
767 }
768
769 // Ready to start a new event.
770 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700771 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700772 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800773 if (isAppSwitchDue) {
774 // The inbound queue is empty so the app switch key we were waiting
775 // for will never arrive. Stop waiting for it.
776 resetPendingAppSwitchLocked(false);
777 isAppSwitchDue = false;
778 }
779
780 // Synthesize a key repeat if appropriate.
781 if (mKeyRepeatState.lastKeyEntry) {
782 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
783 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
784 } else {
785 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
786 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
787 }
788 }
789 }
790
791 // Nothing to do if there is no pending event.
792 if (!mPendingEvent) {
793 return;
794 }
795 } else {
796 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700797 mPendingEvent = mInboundQueue.front();
798 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800799 traceInboundQueueLengthLocked();
800 }
801
802 // Poke user activity for this event.
803 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700804 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800805 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800806 }
807
808 // Now we have an event to dispatch.
809 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700810 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800811 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700812 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800813 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700814 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800815 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700816 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800817 }
818
819 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700820 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800821 }
822
823 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700824 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700825 const ConfigurationChangedEntry& typedEntry =
826 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700827 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700828 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700829 break;
830 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800831
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700832 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700833 const DeviceResetEntry& typedEntry =
834 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700835 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700836 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700837 break;
838 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800839
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100840 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700841 std::shared_ptr<FocusEntry> typedEntry =
842 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100843 dispatchFocusLocked(currentTime, typedEntry);
844 done = true;
845 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
846 break;
847 }
848
Antonio Kantek7242d8b2021-08-05 16:07:20 -0700849 case EventEntry::Type::TOUCH_MODE_CHANGED: {
850 const auto typedEntry = std::static_pointer_cast<TouchModeEntry>(mPendingEvent);
851 dispatchTouchModeChangeLocked(currentTime, typedEntry);
852 done = true;
853 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
854 break;
855 }
856
Prabir Pradhan99987712020-11-10 18:43:05 -0800857 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
858 const auto typedEntry =
859 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
860 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
861 done = true;
862 break;
863 }
864
arthurhungb89ccb02020-12-30 16:19:01 +0800865 case EventEntry::Type::DRAG: {
866 std::shared_ptr<DragEntry> typedEntry =
867 std::static_pointer_cast<DragEntry>(mPendingEvent);
868 dispatchDragLocked(currentTime, typedEntry);
869 done = true;
870 break;
871 }
872
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700873 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700874 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700875 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700876 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700877 resetPendingAppSwitchLocked(true);
878 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700879 } else if (dropReason == DropReason::NOT_DROPPED) {
880 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700881 }
882 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700883 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700884 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700885 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700886 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
887 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700888 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700889 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700890 break;
891 }
892
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700893 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700894 std::shared_ptr<MotionEntry> motionEntry =
895 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700896 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
897 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800898 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700899 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700900 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700901 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700902 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
903 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700904 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700905 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700906 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800907 }
Chris Yef59a2f42020-10-16 12:55:26 -0700908
909 case EventEntry::Type::SENSOR: {
910 std::shared_ptr<SensorEntry> sensorEntry =
911 std::static_pointer_cast<SensorEntry>(mPendingEvent);
912 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
913 dropReason = DropReason::APP_SWITCH;
914 }
915 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
916 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
917 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
918 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
919 dropReason = DropReason::STALE;
920 }
921 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
922 done = true;
923 break;
924 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800925 }
926
927 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700928 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700929 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800930 }
Michael Wright3a981722015-06-10 15:26:13 +0100931 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800932
933 releasePendingEventLocked();
Colin Cross5b799302022-10-18 21:52:41 -0700934 *nextWakeupTime = LLONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800935 }
936}
937
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800938bool InputDispatcher::isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
939 return std::chrono::nanoseconds(currentTime - entry.eventTime) >= mStaleEventTimeout;
940}
941
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700942/**
943 * Return true if the events preceding this incoming motion event should be dropped
944 * Return false otherwise (the default behaviour)
945 */
946bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700947 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -0700948 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700949
950 // Optimize case where the current application is unresponsive and the user
951 // decides to touch a window in a different application.
952 // If the application takes too long to catch up then we drop all events preceding
953 // the touch into the other window.
954 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou9306c382022-09-30 15:30:31 -0700955 const int32_t displayId = motionEntry.displayId;
956 const auto [x, y] = resolveTouchedPosition(motionEntry);
Prabir Pradhand65552b2021-10-07 11:23:50 -0700957 const bool isStylus = isPointerFromStylus(motionEntry, 0 /*pointerIndex*/);
Siarhei Vishniakou9306c382022-09-30 15:30:31 -0700958
chaviw98318de2021-05-19 16:45:23 -0500959 sp<WindowInfoHandle> touchedWindowHandle =
Prabir Pradhand65552b2021-10-07 11:23:50 -0700960 findTouchedWindowAtLocked(displayId, x, y, nullptr, isStylus);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700961 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700962 touchedWindowHandle->getApplicationToken() !=
963 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700964 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700965 ALOGI("Pruning input queue because user touched a different application while waiting "
966 "for %s",
967 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700968 return true;
969 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700970
Prabir Pradhandfabf8a2022-01-21 08:19:30 -0800971 // Alternatively, maybe there's a spy window that could handle this event.
972 const std::vector<sp<WindowInfoHandle>> touchedSpies =
973 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
974 for (const auto& windowHandle : touchedSpies) {
975 const sp<Connection> connection = getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000976 if (connection != nullptr && connection->responsive) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -0800977 // This spy window could take more input. Drop all events preceding this
978 // event, so that the spy window can get a chance to receive the stream.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700979 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
Prabir Pradhandfabf8a2022-01-21 08:19:30 -0800980 "responsive spy window that may handle the event.",
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700981 mAwaitedFocusedApplication->getName().c_str());
982 return true;
983 }
984 }
985 }
986
987 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
988 // yet been processed by some connections, the dispatcher will wait for these motion
989 // events to be processed before dispatching the key event. This is because these motion events
990 // may cause a new window to be launched, which the user might expect to receive focus.
991 // To prevent waiting forever for such events, just send the key to the currently focused window
992 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
993 ALOGD("Received a new pointer down event, stop waiting for events to process and "
994 "just send the pending key event to the focused window.");
995 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700996 }
997 return false;
998}
999
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001000bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001001 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001002 mInboundQueue.push_back(std::move(newEntry));
1003 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001004 traceInboundQueueLengthLocked();
1005
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001006 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001007 case EventEntry::Type::KEY: {
Prabir Pradhan5735a322022-04-11 17:23:34 +00001008 LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1009 "Unexpected untrusted event.");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001010 // Optimize app switch latency.
1011 // If the application takes too long to catch up then we drop all events preceding
1012 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001013 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001014 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001015 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001016 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001017 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001018 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001019 if (DEBUG_APP_SWITCH) {
1020 ALOGD("App switch is pending!");
1021 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001022 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001023 mAppSwitchSawKeyDown = false;
1024 needWake = true;
1025 }
1026 }
1027 }
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001028
1029 // If a new up event comes in, and the pending event with same key code has been asked
1030 // to try again later because of the policy. We have to reset the intercept key wake up
1031 // time for it may have been handled in the policy and could be dropped.
1032 if (keyEntry.action == AKEY_EVENT_ACTION_UP && mPendingEvent &&
1033 mPendingEvent->type == EventEntry::Type::KEY) {
1034 KeyEntry& pendingKey = static_cast<KeyEntry&>(*mPendingEvent);
1035 if (pendingKey.keyCode == keyEntry.keyCode &&
1036 pendingKey.interceptKeyResult ==
Michael Wright5caf55a2022-11-24 22:31:42 +00001037 KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
1038 pendingKey.interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001039 pendingKey.interceptKeyWakeupTime = 0;
1040 needWake = true;
1041 }
1042 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001043 break;
1044 }
1045
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001046 case EventEntry::Type::MOTION: {
Prabir Pradhan5735a322022-04-11 17:23:34 +00001047 LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1048 "Unexpected untrusted event.");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001049 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
1050 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001051 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001052 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001053 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001054 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001055 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001056 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1057 break;
1058 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001059 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001060 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001061 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001062 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001063 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1064 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001065 // nothing to do
1066 break;
1067 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001068 }
1069
1070 return needWake;
1071}
1072
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001073void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001074 // Do not store sensor event in recent queue to avoid flooding the queue.
1075 if (entry->type != EventEntry::Type::SENSOR) {
1076 mRecentQueue.push_back(entry);
1077 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001078 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001079 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080 }
1081}
1082
chaviw98318de2021-05-19 16:45:23 -05001083sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1084 int32_t y, TouchState* touchState,
Prabir Pradhand65552b2021-10-07 11:23:50 -07001085 bool isStylus,
chaviw98318de2021-05-19 16:45:23 -05001086 bool addOutsideTargets,
Siarhei Vishniakou6ebd0692022-10-20 15:05:45 -07001087 bool ignoreDragWindow) const {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001088 if (addOutsideTargets && touchState == nullptr) {
1089 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001090 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001091 // Traverse windows from front to back to find touched window.
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001092 const auto& windowHandles = getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05001093 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001094 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001095 continue;
1096 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001097
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001098 const WindowInfo& info = *windowHandle->getInfo();
Prabir Pradhand65552b2021-10-07 11:23:50 -07001099 if (!info.isSpy() && windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001100 return windowHandle;
1101 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001102
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08001103 if (addOutsideTargets &&
1104 info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001105 touchState->addOrUpdateWindow(windowHandle, InputTarget::Flags::DISPATCH_AS_OUTSIDE,
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001106 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001107 }
1108 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001109 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001110}
1111
Prabir Pradhand65552b2021-10-07 11:23:50 -07001112std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
1113 int32_t displayId, int32_t x, int32_t y, bool isStylus) const {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001114 // Traverse windows from front to back and gather the touched spy windows.
1115 std::vector<sp<WindowInfoHandle>> spyWindows;
1116 const auto& windowHandles = getWindowHandlesLocked(displayId);
1117 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1118 const WindowInfo& info = *windowHandle->getInfo();
1119
Prabir Pradhand65552b2021-10-07 11:23:50 -07001120 if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001121 continue;
1122 }
1123 if (!info.isSpy()) {
1124 // The first touched non-spy window was found, so return the spy windows touched so far.
1125 return spyWindows;
1126 }
1127 spyWindows.push_back(windowHandle);
1128 }
1129 return spyWindows;
1130}
1131
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001132void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001133 const char* reason;
1134 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001135 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001136 if (DEBUG_INBOUND_EVENT_DETAILS) {
1137 ALOGD("Dropped event because policy consumed it.");
1138 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001139 reason = "inbound event was dropped because the policy consumed it";
1140 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001141 case DropReason::DISABLED:
1142 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001143 ALOGI("Dropped event because input dispatch is disabled.");
1144 }
1145 reason = "inbound event was dropped because input dispatch is disabled";
1146 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001147 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001148 ALOGI("Dropped event because of pending overdue app switch.");
1149 reason = "inbound event was dropped because of pending overdue app switch";
1150 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001151 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001152 ALOGI("Dropped event because the current application is not responding and the user "
1153 "has started interacting with a different application.");
1154 reason = "inbound event was dropped because the current application is not responding "
1155 "and the user has started interacting with a different application";
1156 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001157 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001158 ALOGI("Dropped event because it is stale.");
1159 reason = "inbound event was dropped because it is stale";
1160 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001161 case DropReason::NO_POINTER_CAPTURE:
1162 ALOGI("Dropped event because there is no window with Pointer Capture.");
1163 reason = "inbound event was dropped because there is no window with Pointer Capture";
1164 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001165 case DropReason::NOT_DROPPED: {
1166 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001167 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001168 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001169 }
1170
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001171 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001172 case EventEntry::Type::KEY: {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001173 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001174 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001175 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001176 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001177 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001178 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1179 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001180 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, reason);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001181 synthesizeCancelationEventsForAllConnectionsLocked(options);
1182 } else {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001183 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
1184 reason);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001185 synthesizeCancelationEventsForAllConnectionsLocked(options);
1186 }
1187 break;
1188 }
Chris Yef59a2f42020-10-16 12:55:26 -07001189 case EventEntry::Type::SENSOR: {
1190 break;
1191 }
arthurhungb89ccb02020-12-30 16:19:01 +08001192 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1193 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001194 break;
1195 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001196 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001197 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001198 case EventEntry::Type::CONFIGURATION_CHANGED:
1199 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001200 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001201 break;
1202 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001203 }
1204}
1205
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001206static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001207 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1208 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001209}
1210
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001211bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1212 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1213 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1214 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001215}
1216
1217bool InputDispatcher::isAppSwitchPendingLocked() {
Colin Cross5b799302022-10-18 21:52:41 -07001218 return mAppSwitchDueTime != LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001219}
1220
1221void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
Colin Cross5b799302022-10-18 21:52:41 -07001222 mAppSwitchDueTime = LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001223
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001224 if (DEBUG_APP_SWITCH) {
1225 if (handled) {
1226 ALOGD("App switch has arrived.");
1227 } else {
1228 ALOGD("App switch was abandoned.");
1229 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001230 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001231}
1232
Michael Wrightd02c5b62014-02-10 15:10:22 -08001233bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001234 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001235}
1236
Prabir Pradhancef936d2021-07-21 16:17:52 +00001237bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001238 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001239 return false;
1240 }
1241
1242 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001243 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001244 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001245 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1246 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001247 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001248 return true;
1249}
1250
Prabir Pradhancef936d2021-07-21 16:17:52 +00001251void InputDispatcher::postCommandLocked(Command&& command) {
1252 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001253}
1254
1255void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001256 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001257 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001258 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001259 releaseInboundEventLocked(entry);
1260 }
1261 traceInboundQueueLengthLocked();
1262}
1263
1264void InputDispatcher::releasePendingEventLocked() {
1265 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001266 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001267 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001268 }
1269}
1270
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001271void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001272 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001273 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001274 if (DEBUG_DISPATCH_CYCLE) {
1275 ALOGD("Injected inbound event was dropped.");
1276 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001277 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001278 }
1279 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001280 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001281 }
1282 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001283}
1284
1285void InputDispatcher::resetKeyRepeatLocked() {
1286 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001287 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001288 }
1289}
1290
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001291std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1292 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001293
Michael Wright2e732952014-09-24 13:26:59 -07001294 uint32_t policyFlags = entry->policyFlags &
1295 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001296
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001297 std::shared_ptr<KeyEntry> newEntry =
1298 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1299 entry->source, entry->displayId, policyFlags, entry->action,
1300 entry->flags, entry->keyCode, entry->scanCode,
1301 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001302
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001303 newEntry->syntheticRepeat = true;
1304 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001305 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001306 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001307}
1308
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001309bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001310 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001311 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1312 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1313 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001314
1315 // Reset key repeating in case a keyboard device was added or removed or something.
1316 resetKeyRepeatLocked();
1317
1318 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001319 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1320 scoped_unlock unlock(mLock);
1321 mPolicy->notifyConfigurationChanged(eventTime);
1322 };
1323 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001324 return true;
1325}
1326
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001327bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1328 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001329 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1330 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1331 entry.deviceId);
1332 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001333
liushenxiang42232912021-05-21 20:24:09 +08001334 // Reset key repeating in case a keyboard device was disabled or enabled.
1335 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1336 resetKeyRepeatLocked();
1337 }
1338
Michael Wrightfb04fd52022-11-24 22:31:11 +00001339 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001340 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001341 synthesizeCancelationEventsForAllConnectionsLocked(options);
1342 return true;
1343}
1344
Vishnu Nairad321cd2020-08-20 16:40:21 -07001345void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001346 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001347 if (mPendingEvent != nullptr) {
1348 // Move the pending event to the front of the queue. This will give the chance
1349 // for the pending event to get dispatched to the newly focused window
1350 mInboundQueue.push_front(mPendingEvent);
1351 mPendingEvent = nullptr;
1352 }
1353
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001354 std::unique_ptr<FocusEntry> focusEntry =
1355 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1356 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001357
1358 // This event should go to the front of the queue, but behind all other focus events
1359 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001360 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001361 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001362 [](const std::shared_ptr<EventEntry>& event) {
1363 return event->type == EventEntry::Type::FOCUS;
1364 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001365
1366 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001367 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001368}
1369
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001370void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001371 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001372 if (channel == nullptr) {
1373 return; // Window has gone away
1374 }
1375 InputTarget target;
1376 target.inputChannel = channel;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001377 target.flags = InputTarget::Flags::DISPATCH_AS_IS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001378 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001379 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1380 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001381 std::string reason = std::string("reason=").append(entry->reason);
1382 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001383 dispatchEventLocked(currentTime, entry, {target});
1384}
1385
Prabir Pradhan99987712020-11-10 18:43:05 -08001386void InputDispatcher::dispatchPointerCaptureChangedLocked(
1387 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1388 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001389 dropReason = DropReason::NOT_DROPPED;
1390
Prabir Pradhan99987712020-11-10 18:43:05 -08001391 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001392 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001393
1394 if (entry->pointerCaptureRequest.enable) {
1395 // Enable Pointer Capture.
1396 if (haveWindowWithPointerCapture &&
1397 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
Prabir Pradhan7092e262022-05-03 16:51:09 +00001398 // This can happen if pointer capture is disabled and re-enabled before we notify the
1399 // app of the state change, so there is no need to notify the app.
1400 ALOGI("Skipping dispatch of Pointer Capture being enabled: no state change.");
1401 return;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001402 }
1403 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001404 // This can happen if a window requests capture and immediately releases capture.
1405 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001406 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001407 return;
1408 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001409 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1410 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1411 return;
1412 }
1413
Vishnu Nairc519ff72021-01-21 08:23:08 -08001414 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001415 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1416 mWindowTokenWithPointerCapture = token;
1417 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001418 // Disable Pointer Capture.
1419 // We do not check if the sequence number matches for requests to disable Pointer Capture
1420 // for two reasons:
1421 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1422 // to disable capture with the same sequence number: one generated by
1423 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1424 // Capture being disabled in InputReader.
1425 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1426 // actual Pointer Capture state that affects events being generated by input devices is
1427 // in InputReader.
1428 if (!haveWindowWithPointerCapture) {
1429 // Pointer capture was already forcefully disabled because of focus change.
1430 dropReason = DropReason::NOT_DROPPED;
1431 return;
1432 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001433 token = mWindowTokenWithPointerCapture;
1434 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001435 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001436 setPointerCaptureLocked(false);
1437 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001438 }
1439
1440 auto channel = getInputChannelLocked(token);
1441 if (channel == nullptr) {
1442 // Window has gone away, clean up Pointer Capture state.
1443 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001444 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001445 setPointerCaptureLocked(false);
1446 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001447 return;
1448 }
1449 InputTarget target;
1450 target.inputChannel = channel;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001451 target.flags = InputTarget::Flags::DISPATCH_AS_IS;
Prabir Pradhan99987712020-11-10 18:43:05 -08001452 entry->dispatchInProgress = true;
1453 dispatchEventLocked(currentTime, entry, {target});
1454
1455 dropReason = DropReason::NOT_DROPPED;
1456}
1457
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001458void InputDispatcher::dispatchTouchModeChangeLocked(nsecs_t currentTime,
1459 const std::shared_ptr<TouchModeEntry>& entry) {
1460 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Antonio Kantek15beb512022-06-13 22:35:41 +00001461 getWindowHandlesLocked(entry->displayId);
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001462 if (windowHandles.empty()) {
1463 return;
1464 }
1465 const std::vector<InputTarget> inputTargets =
1466 getInputTargetsFromWindowHandlesLocked(windowHandles);
1467 if (inputTargets.empty()) {
1468 return;
1469 }
1470 entry->dispatchInProgress = true;
1471 dispatchEventLocked(currentTime, entry, inputTargets);
1472}
1473
1474std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1475 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1476 std::vector<InputTarget> inputTargets;
1477 for (const sp<WindowInfoHandle>& handle : windowHandles) {
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001478 const sp<IBinder>& token = handle->getToken();
1479 if (token == nullptr) {
1480 continue;
1481 }
1482 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1483 if (channel == nullptr) {
1484 continue; // Window has gone away
1485 }
1486 InputTarget target;
1487 target.inputChannel = channel;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001488 target.flags = InputTarget::Flags::DISPATCH_AS_IS;
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001489 inputTargets.push_back(target);
1490 }
1491 return inputTargets;
1492}
1493
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001494bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001495 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001496 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001497 if (!entry->dispatchInProgress) {
1498 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1499 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1500 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1501 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001502 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001503 // We have seen two identical key downs in a row which indicates that the device
1504 // driver is automatically generating key repeats itself. We take note of the
1505 // repeat here, but we disable our own next key repeat timer since it is clear that
1506 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001507 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1508 // Make sure we don't get key down from a different device. If a different
1509 // device Id has same key pressed down, the new device Id will replace the
1510 // current one to hold the key repeat with repeat count reset.
1511 // In the future when got a KEY_UP on the device id, drop it and do not
1512 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001513 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1514 resetKeyRepeatLocked();
Colin Cross5b799302022-10-18 21:52:41 -07001515 mKeyRepeatState.nextRepeatTime = LLONG_MAX; // don't generate repeats ourselves
Michael Wrightd02c5b62014-02-10 15:10:22 -08001516 } else {
1517 // Not a repeat. Save key down state in case we do see a repeat later.
1518 resetKeyRepeatLocked();
1519 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1520 }
1521 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001522 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1523 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001524 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001525 if (DEBUG_INBOUND_EVENT_DETAILS) {
1526 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1527 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001528 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001529 resetKeyRepeatLocked();
1530 }
1531
1532 if (entry->repeatCount == 1) {
1533 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1534 } else {
1535 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1536 }
1537
1538 entry->dispatchInProgress = true;
1539
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001540 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001541 }
1542
1543 // Handle case where the policy asked us to try again later last time.
Michael Wright5caf55a2022-11-24 22:31:42 +00001544 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001545 if (currentTime < entry->interceptKeyWakeupTime) {
1546 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1547 *nextWakeupTime = entry->interceptKeyWakeupTime;
1548 }
1549 return false; // wait until next wakeup
1550 }
Michael Wright5caf55a2022-11-24 22:31:42 +00001551 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001552 entry->interceptKeyWakeupTime = 0;
1553 }
1554
1555 // Give the policy a chance to intercept the key.
Michael Wright5caf55a2022-11-24 22:31:42 +00001556 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001557 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001558 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001559 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001560
1561 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1562 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1563 };
1564 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001565 return false; // wait for the command to run
1566 } else {
Michael Wright5caf55a2022-11-24 22:31:42 +00001567 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001568 }
Michael Wright5caf55a2022-11-24 22:31:42 +00001569 } else if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001570 if (*dropReason == DropReason::NOT_DROPPED) {
1571 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001572 }
1573 }
1574
1575 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001576 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001577 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001578 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1579 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001580 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001581 return true;
1582 }
1583
1584 // Identify targets.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001585 InputEventInjectionResult injectionResult;
1586 sp<WindowInfoHandle> focusedWindow =
1587 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime,
1588 /*byref*/ injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001589 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001590 return false;
1591 }
1592
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001593 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001594 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001595 return true;
1596 }
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001597 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
1598
1599 std::vector<InputTarget> inputTargets;
1600 addWindowTargetLocked(focusedWindow,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001601 InputTarget::Flags::FOREGROUND | InputTarget::Flags::DISPATCH_AS_IS,
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001602 BitSet32(0), getDownTime(*entry), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001603
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001604 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001605 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001606
1607 // Dispatch the key.
1608 dispatchEventLocked(currentTime, entry, inputTargets);
1609 return true;
1610}
1611
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001612void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001613 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1614 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1615 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1616 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1617 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1618 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1619 entry.metaState, entry.repeatCount, entry.downTime);
1620 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001621}
1622
Prabir Pradhancef936d2021-07-21 16:17:52 +00001623void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1624 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001625 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001626 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1627 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1628 "source=0x%x, sensorType=%s",
1629 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001630 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001631 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001632 auto command = [this, entry]() REQUIRES(mLock) {
1633 scoped_unlock unlock(mLock);
1634
1635 if (entry->accuracyChanged) {
1636 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1637 }
1638 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1639 entry->hwTimestamp, entry->values);
1640 };
1641 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001642}
1643
1644bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001645 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1646 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001647 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001648 }
Chris Yef59a2f42020-10-16 12:55:26 -07001649 { // acquire lock
1650 std::scoped_lock _l(mLock);
1651
1652 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1653 std::shared_ptr<EventEntry> entry = *it;
1654 if (entry->type == EventEntry::Type::SENSOR) {
1655 it = mInboundQueue.erase(it);
1656 releaseInboundEventLocked(entry);
1657 }
1658 }
1659 }
1660 return true;
1661}
1662
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001663bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001664 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001665 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001666 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001667 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001668 entry->dispatchInProgress = true;
1669
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001670 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001671 }
1672
1673 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001674 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001675 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001676 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1677 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001678 return true;
1679 }
1680
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001681 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001682
1683 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001684 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001685
1686 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001687 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001688 if (isPointerEvent) {
1689 // Pointer event. (eg. touchscreen)
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00001690
1691 if (mDragState &&
1692 (entry->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN) {
1693 // If drag and drop ongoing and pointer down occur: pilfer drag window pointers
1694 pilferPointersLocked(mDragState->dragWindow->getToken());
1695 }
1696
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001697 std::vector<TouchedWindow> touchedWindows =
Siarhei Vishniakou4fe57392022-10-25 13:44:30 -07001698 findTouchedWindowTargetsLocked(currentTime, *entry, &conflictingPointerActions,
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001699 /*byref*/ injectionResult);
1700 for (const TouchedWindow& touchedWindow : touchedWindows) {
1701 LOG_ALWAYS_FATAL_IF(injectionResult != InputEventInjectionResult::SUCCEEDED,
1702 "Shouldn't be adding window if the injection didn't succeed.");
1703 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
1704 touchedWindow.pointerIds, touchedWindow.firstDownTimeInTarget,
1705 inputTargets);
1706 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001707 } else {
1708 // Non touch event. (eg. trackball)
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001709 sp<WindowInfoHandle> focusedWindow =
1710 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime, injectionResult);
1711 if (injectionResult == InputEventInjectionResult::SUCCEEDED) {
1712 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
1713 addWindowTargetLocked(focusedWindow,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001714 InputTarget::Flags::FOREGROUND |
1715 InputTarget::Flags::DISPATCH_AS_IS,
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001716 BitSet32(0), getDownTime(*entry), inputTargets);
1717 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001718 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001719 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001720 return false;
1721 }
1722
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001723 setInjectionResult(*entry, injectionResult);
Prabir Pradhan5735a322022-04-11 17:23:34 +00001724 if (injectionResult == InputEventInjectionResult::TARGET_MISMATCH) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001725 return true;
1726 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001727 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001728 CancelationOptions::Mode mode(
1729 isPointerEvent ? CancelationOptions::Mode::CANCEL_POINTER_EVENTS
1730 : CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS);
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001731 CancelationOptions options(mode, "input event injection failed");
1732 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001733 return true;
1734 }
1735
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001736 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001737 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001738
1739 // Dispatch the motion.
1740 if (conflictingPointerActions) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001741 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001742 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001743 synthesizeCancelationEventsForAllConnectionsLocked(options);
1744 }
1745 dispatchEventLocked(currentTime, entry, inputTargets);
1746 return true;
1747}
1748
chaviw98318de2021-05-19 16:45:23 -05001749void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
Arthur Hung54745652022-04-20 07:17:41 +00001750 bool isExiting, const int32_t rawX,
1751 const int32_t rawY) {
1752 const vec2 xy = windowHandle->getInfo()->transform.transform(vec2(rawX, rawY));
arthurhungb89ccb02020-12-30 16:19:01 +08001753 std::unique_ptr<DragEntry> dragEntry =
Arthur Hung54745652022-04-20 07:17:41 +00001754 std::make_unique<DragEntry>(mIdGenerator.nextId(), now(), windowHandle->getToken(),
1755 isExiting, xy.x, xy.y);
arthurhungb89ccb02020-12-30 16:19:01 +08001756
1757 enqueueInboundEventLocked(std::move(dragEntry));
1758}
1759
1760void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1761 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1762 if (channel == nullptr) {
1763 return; // Window has gone away
1764 }
1765 InputTarget target;
1766 target.inputChannel = channel;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001767 target.flags = InputTarget::Flags::DISPATCH_AS_IS;
arthurhungb89ccb02020-12-30 16:19:01 +08001768 entry->dispatchInProgress = true;
1769 dispatchEventLocked(currentTime, entry, {target});
1770}
1771
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001772void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001773 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08001774 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=%s, displayId=%" PRId32
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001775 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001776 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001777 "metaState=0x%x, buttonState=0x%x,"
1778 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08001779 prefix, entry.eventTime, entry.deviceId,
1780 inputEventSourceToString(entry.source).c_str(), entry.displayId, entry.policyFlags,
1781 MotionEvent::actionToString(entry.action).c_str(), entry.actionButton, entry.flags,
1782 entry.metaState, entry.buttonState, entry.edgeFlags, entry.xPrecision,
1783 entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001784
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001785 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1786 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1787 "x=%f, y=%f, pressure=%f, size=%f, "
1788 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1789 "orientation=%f",
1790 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1791 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1792 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1793 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1794 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1795 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1796 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1797 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1798 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1799 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1800 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001801 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001802}
1803
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001804void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1805 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001806 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001807 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001808 if (DEBUG_DISPATCH_CYCLE) {
1809 ALOGD("dispatchEventToCurrentInputTargets");
1810 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001811
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001812 updateInteractionTokensLocked(*eventEntry, inputTargets);
1813
Michael Wrightd02c5b62014-02-10 15:10:22 -08001814 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1815
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001816 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001817
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001818 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001819 sp<Connection> connection =
1820 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001821 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001822 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001823 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001824 if (DEBUG_FOCUS) {
1825 ALOGD("Dropping event delivery to target with channel '%s' because it "
1826 "is no longer registered with the input dispatcher.",
1827 inputTarget.inputChannel->getName().c_str());
1828 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001829 }
1830 }
1831}
1832
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001833void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1834 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1835 // If the policy decides to close the app, we will get a channel removal event via
1836 // unregisterInputChannel, and will clean up the connection that way. We are already not
1837 // sending new pointers to the connection when it blocked, but focused events will continue to
1838 // pile up.
1839 ALOGW("Canceling events for %s because it is unresponsive",
1840 connection->inputChannel->getName().c_str());
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08001841 if (connection->status == Connection::Status::NORMAL) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001842 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001843 "application not responding");
1844 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001845 }
1846}
1847
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001848void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001849 if (DEBUG_FOCUS) {
1850 ALOGD("Resetting ANR timeouts.");
1851 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001852
1853 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001854 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001855 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001856}
1857
Tiger Huang721e26f2018-07-24 22:26:19 +08001858/**
1859 * Get the display id that the given event should go to. If this event specifies a valid display id,
1860 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1861 * Focused display is the display that the user most recently interacted with.
1862 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001863int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001864 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001865 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001866 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001867 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1868 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001869 break;
1870 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001871 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001872 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1873 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001874 break;
1875 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00001876 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001877 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001878 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001879 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001880 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001881 case EventEntry::Type::SENSOR:
1882 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001883 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001884 return ADISPLAY_ID_NONE;
1885 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001886 }
1887 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1888}
1889
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001890bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1891 const char* focusedWindowName) {
1892 if (mAnrTracker.empty()) {
1893 // already processed all events that we waited for
1894 mKeyIsWaitingForEventsTimeout = std::nullopt;
1895 return false;
1896 }
1897
1898 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1899 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001900 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001901 mKeyIsWaitingForEventsTimeout = currentTime +
1902 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1903 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001904 return true;
1905 }
1906
1907 // We still have pending events, and already started the timer
1908 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1909 return true; // Still waiting
1910 }
1911
1912 // Waited too long, and some connection still hasn't processed all motions
1913 // Just send the key to the focused window
1914 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1915 focusedWindowName);
1916 mKeyIsWaitingForEventsTimeout = std::nullopt;
1917 return false;
1918}
1919
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001920sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked(
1921 nsecs_t currentTime, const EventEntry& entry, nsecs_t* nextWakeupTime,
1922 InputEventInjectionResult& outInjectionResult) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001923 std::string reason;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001924 outInjectionResult = InputEventInjectionResult::FAILED; // Default result
Michael Wrightd02c5b62014-02-10 15:10:22 -08001925
Tiger Huang721e26f2018-07-24 22:26:19 +08001926 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001927 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001928 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001929 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1930
Michael Wrightd02c5b62014-02-10 15:10:22 -08001931 // If there is no currently focused window and no focused application
1932 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001933 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1934 ALOGI("Dropping %s event because there is no focused window or focused application in "
1935 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08001936 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001937 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001938 }
1939
Vishnu Nair062a8672021-09-03 16:07:44 -07001940 // Drop key events if requested by input feature
1941 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001942 return nullptr;
Vishnu Nair062a8672021-09-03 16:07:44 -07001943 }
1944
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001945 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1946 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1947 // start interacting with another application via touch (app switch). This code can be removed
1948 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1949 // an app is expected to have a focused window.
1950 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1951 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1952 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001953 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1954 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1955 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001956 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001957 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001958 ALOGW("Waiting because no window has focus but %s may eventually add a "
1959 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001960 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001961 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001962 outInjectionResult = InputEventInjectionResult::PENDING;
1963 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001964 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1965 // Already raised ANR. Drop the event
1966 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08001967 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001968 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001969 } else {
1970 // Still waiting for the focused window
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001971 outInjectionResult = InputEventInjectionResult::PENDING;
1972 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001973 }
1974 }
1975
1976 // we have a valid, non-null focused window
1977 resetNoFocusedWindowTimeoutLocked();
1978
Prabir Pradhan5735a322022-04-11 17:23:34 +00001979 // Verify targeted injection.
1980 if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) {
1981 ALOGW("Dropping injected event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001982 outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
1983 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001984 }
1985
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08001986 if (focusedWindowHandle->getInfo()->inputConfig.test(
1987 WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001988 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001989 outInjectionResult = InputEventInjectionResult::PENDING;
1990 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001991 }
1992
1993 // If the event is a key event, then we must wait for all previous events to
1994 // complete before delivering it because previous events may have the
1995 // side-effect of transferring focus to a different window and we want to
1996 // ensure that the following keys are sent to the new window.
1997 //
1998 // Suppose the user touches a button in a window then immediately presses "A".
1999 // If the button causes a pop-up window to appear then we want to ensure that
2000 // the "A" key is delivered to the new pop-up window. This is because users
2001 // often anticipate pending UI changes when typing on a keyboard.
2002 // To obtain this behavior, we must serialize key events with respect to all
2003 // prior input events.
2004 if (entry.type == EventEntry::Type::KEY) {
2005 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
2006 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002007 outInjectionResult = InputEventInjectionResult::PENDING;
2008 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002009 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002010 }
2011
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002012 outInjectionResult = InputEventInjectionResult::SUCCEEDED;
2013 return focusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002014}
2015
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002016/**
2017 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
2018 * that are currently unresponsive.
2019 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002020std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
2021 const std::vector<Monitor>& monitors) const {
2022 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002023 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002024 [this](const Monitor& monitor) REQUIRES(mLock) {
2025 sp<Connection> connection =
2026 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002027 if (connection == nullptr) {
2028 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002029 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002030 return false;
2031 }
2032 if (!connection->responsive) {
2033 ALOGW("Unresponsive monitor %s will not get the new gesture",
2034 connection->inputChannel->getName().c_str());
2035 return false;
2036 }
2037 return true;
2038 });
2039 return responsiveMonitors;
2040}
2041
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002042/**
2043 * In general, touch should be always split between windows. Some exceptions:
2044 * 1. Don't split touch is if we have an active pointer down, and a new pointer is going down that's
2045 * from the same device, *and* the window that's receiving the current pointer does not support
2046 * split touch.
2047 * 2. Don't split mouse events
2048 */
2049bool InputDispatcher::shouldSplitTouch(const TouchState& touchState,
2050 const MotionEntry& entry) const {
2051 if (isFromSource(entry.source, AINPUT_SOURCE_MOUSE)) {
2052 // We should never split mouse events
2053 return false;
2054 }
2055 for (const TouchedWindow& touchedWindow : touchState.windows) {
2056 if (touchedWindow.windowHandle->getInfo()->isSpy()) {
2057 // Spy windows should not affect whether or not touch is split.
2058 continue;
2059 }
2060 if (touchedWindow.windowHandle->getInfo()->supportsSplitTouch()) {
2061 continue;
2062 }
2063 // Eventually, touchedWindow will contain the deviceId of each pointer that's currently
2064 // being sent there. For now, use deviceId from touch state.
2065 if (entry.deviceId == touchState.deviceId && !touchedWindow.pointerIds.isEmpty()) {
2066 return false;
2067 }
2068 }
2069 return true;
2070}
2071
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002072std::vector<TouchedWindow> InputDispatcher::findTouchedWindowTargetsLocked(
Siarhei Vishniakou4fe57392022-10-25 13:44:30 -07002073 nsecs_t currentTime, const MotionEntry& entry, bool* outConflictingPointerActions,
2074 InputEventInjectionResult& outInjectionResult) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002075 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002076
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002077 std::vector<TouchedWindow> touchedWindows;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002078 // For security reasons, we defer updating the touch state until we are sure that
2079 // event injection will be allowed.
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002080 const int32_t displayId = entry.displayId;
2081 const int32_t action = entry.action;
2082 const int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002083
2084 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002085 outInjectionResult = InputEventInjectionResult::PENDING;
chaviw98318de2021-05-19 16:45:23 -05002086 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
2087 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002088
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002089 // Copy current touch state into tempTouchState.
2090 // This state will be used to update mTouchStatesByDisplay at the end of this function.
2091 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07002092 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002093 TouchState tempTouchState;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002094 if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
2095 oldState = &(it->second);
Prabir Pradhane680f9b2022-02-04 04:24:00 -08002096 tempTouchState = *oldState;
Jeff Brownf086ddb2014-02-11 14:28:48 -08002097 }
2098
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002099 bool isSplit = shouldSplitTouch(tempTouchState, entry);
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07002100 const bool switchedDevice = (oldState != nullptr) &&
Siarhei Vishniakou5cee1e32022-11-29 12:35:39 -08002101 (oldState->deviceId != entry.deviceId || oldState->source != entry.source);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002102
2103 const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2104 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2105 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
2106 const bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2107 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002108 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Siarhei Vishniakou5cee1e32022-11-29 12:35:39 -08002109
Michael Wrightd02c5b62014-02-10 15:10:22 -08002110 if (newGesture) {
2111 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou3ad385b2022-11-04 10:09:53 -07002112 if (switchedDevice && tempTouchState.isDown() && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002113 ALOGI("Dropping event because a pointer for a different device is already down "
2114 "in display %" PRId32,
2115 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002116 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002117 outInjectionResult = InputEventInjectionResult::FAILED;
Siarhei Vishniakouf0ab2c82022-10-25 18:15:28 -07002118 return touchedWindows; // wrong device
Michael Wrightd02c5b62014-02-10 15:10:22 -08002119 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002120 tempTouchState.reset();
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002121 tempTouchState.deviceId = entry.deviceId;
2122 tempTouchState.source = entry.source;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002123 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002124 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002125 ALOGI("Dropping move event because a pointer for a different device is already active "
2126 "in display %" PRId32,
2127 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002128 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002129 outInjectionResult = InputEventInjectionResult::FAILED;
Siarhei Vishniakouf0ab2c82022-10-25 18:15:28 -07002130 return touchedWindows; // wrong device
Michael Wrightd02c5b62014-02-10 15:10:22 -08002131 }
2132
2133 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2134 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07002135 const auto [x, y] = resolveTouchedPosition(entry);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002136 const int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002137 const bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Prabir Pradhand65552b2021-10-07 11:23:50 -07002138 const bool isStylus = isPointerFromStylus(entry, pointerIndex);
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002139 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
Prabir Pradhand65552b2021-10-07 11:23:50 -07002140 isStylus, isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00002141
Michael Wrightd02c5b62014-02-10 15:10:22 -08002142 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002143 if (newTouchedWindowHandle == nullptr) {
Arthur Hungb3307ee2021-10-14 10:57:37 +00002144 ALOGD("No new touched window at (%" PRId32 ", %" PRId32 ") in display %" PRId32, x, y,
2145 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002146 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002147 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002148 }
2149
Prabir Pradhan5735a322022-04-11 17:23:34 +00002150 // Verify targeted injection.
2151 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2152 ALOGW("Dropping injected touch event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002153 outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
Prabir Pradhan5735a322022-04-11 17:23:34 +00002154 newTouchedWindowHandle = nullptr;
2155 goto Failed;
2156 }
2157
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002158 // Figure out whether splitting will be allowed for this window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002159 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002160 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2161 // New window supports splitting, but we should never split mouse events.
2162 isSplit = !isFromMouse;
2163 } else if (isSplit) {
2164 // New window does not support splitting but we have already split events.
2165 // Ignore the new window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002166 newTouchedWindowHandle = nullptr;
2167 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002168 } else {
2169 // No window is touched, so set split to true. This will allow the next pointer down to
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002170 // be delivered to a new window which supports split touch. Pointers from a mouse device
2171 // should never be split.
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002172 isSplit = !isFromMouse;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002173 }
2174
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002175 // Update hover state.
Michael Wright3dd60e22019-03-27 22:06:44 +00002176 if (newTouchedWindowHandle != nullptr) {
Garfield Tandf26e862020-07-01 20:18:19 -07002177 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2178 newHoverWindowHandle = nullptr;
2179 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002180 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002181 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002182 }
2183
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002184 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002185 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002186 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002187 // Process the foreground window first so that it is the first to receive the event.
2188 newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002189 }
2190
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002191 if (newTouchedWindows.empty()) {
2192 ALOGI("Dropping event because there is no touchable window at (%d, %d) on display %d.",
2193 x, y, displayId);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002194 outInjectionResult = InputEventInjectionResult::FAILED;
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002195 goto Failed;
2196 }
2197
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002198 for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07002199 if (!canWindowReceiveMotionLocked(windowHandle, entry)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002200 continue;
2201 }
2202
2203 // Set target flags.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002204 ftl::Flags<InputTarget::Flags> targetFlags = InputTarget::Flags::DISPATCH_AS_IS;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002205
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002206 if (canReceiveForegroundTouches(*windowHandle->getInfo())) {
2207 // There should only be one touched window that can be "foreground" for the pointer.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002208 targetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002209 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002210
2211 if (isSplit) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002212 targetFlags |= InputTarget::Flags::SPLIT;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002213 }
2214 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002215 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002216 } else if (isWindowObscuredLocked(windowHandle)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002217 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002218 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002219
2220 // Update the temporary touch state.
2221 BitSet32 pointerIds;
Arthur Hungb75c2aa2022-07-15 09:35:36 +00002222 pointerIds.markBit(entry.pointerProperties[pointerIndex].id);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002223
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002224 tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds,
2225 entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002226 }
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00002227
2228 // If any existing window is pilfering pointers from newly added window, remove it
2229 BitSet32 canceledPointers = BitSet32(0);
2230 for (const TouchedWindow& window : tempTouchState.windows) {
2231 if (window.isPilferingPointers) {
2232 canceledPointers |= window.pointerIds;
2233 }
2234 }
2235 tempTouchState.cancelPointersForNonPilferingWindows(canceledPointers);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002236 } else {
2237 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2238
2239 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou3ad385b2022-11-04 10:09:53 -07002240 if (!tempTouchState.isDown()) {
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -08002241 ALOGD_IF(DEBUG_FOCUS,
2242 "Dropping event because the pointer is not down or we previously "
2243 "dropped the pointer down event in display %" PRId32 ": %s",
2244 displayId, entry.getDescription().c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002245 outInjectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002246 goto Failed;
2247 }
2248
arthurhung6d4bed92021-03-17 11:59:33 +08002249 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002250
Michael Wrightd02c5b62014-02-10 15:10:22 -08002251 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002252 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002253 tempTouchState.isSlippery()) {
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07002254 const auto [x, y] = resolveTouchedPosition(entry);
Prabir Pradhand65552b2021-10-07 11:23:50 -07002255 const bool isStylus = isPointerFromStylus(entry, 0 /*pointerIndex*/);
chaviw98318de2021-05-19 16:45:23 -05002256 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002257 tempTouchState.getFirstForegroundWindowHandle();
Prabir Pradhand65552b2021-10-07 11:23:50 -07002258 newTouchedWindowHandle =
2259 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState, isStylus);
Vishnu Nair062a8672021-09-03 16:07:44 -07002260
Prabir Pradhan5735a322022-04-11 17:23:34 +00002261 // Verify targeted injection.
2262 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2263 ALOGW("Dropping injected event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002264 outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
Prabir Pradhan5735a322022-04-11 17:23:34 +00002265 newTouchedWindowHandle = nullptr;
2266 goto Failed;
2267 }
2268
Vishnu Nair062a8672021-09-03 16:07:44 -07002269 // Drop touch events if requested by input feature
2270 if (newTouchedWindowHandle != nullptr &&
2271 shouldDropInput(entry, newTouchedWindowHandle)) {
2272 newTouchedWindowHandle = nullptr;
2273 }
2274
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002275 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2276 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002277 if (DEBUG_FOCUS) {
2278 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2279 oldTouchedWindowHandle->getName().c_str(),
2280 newTouchedWindowHandle->getName().c_str(), displayId);
2281 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002282 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002283 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002284 InputTarget::Flags::DISPATCH_AS_SLIPPERY_EXIT,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002285 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002286
2287 // Make a slippery entrance into the new window.
2288 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002289 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002290 }
2291
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002292 ftl::Flags<InputTarget::Flags> targetFlags =
2293 InputTarget::Flags::DISPATCH_AS_SLIPPERY_ENTER;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002294 if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002295 targetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002296 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002297 if (isSplit) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002298 targetFlags |= InputTarget::Flags::SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002299 }
2300 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002301 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002302 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002303 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002304 }
2305
2306 BitSet32 pointerIds;
Arthur Hungb75c2aa2022-07-15 09:35:36 +00002307 pointerIds.markBit(entry.pointerProperties[0].id);
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002308 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds,
2309 entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002310 }
2311 }
Arthur Hung96483742022-11-15 03:30:48 +00002312
2313 // Update the pointerIds for non-splittable when it received pointer down.
2314 if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2315 // If no split, we suppose all touched windows should receive pointer down.
2316 const int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2317 for (size_t i = 0; i < tempTouchState.windows.size(); i++) {
2318 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2319 // Ignore drag window for it should just track one pointer.
2320 if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
2321 continue;
2322 }
2323 touchedWindow.pointerIds.markBit(entry.pointerProperties[pointerIndex].id);
2324 }
2325 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002326 }
2327
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002328 // Update dispatching for hover enter and exit.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002329 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002330 // Let the previous window know that the hover sequence is over, unless we already did
2331 // it when dispatching it as is to newTouchedWindowHandle.
Garfield Tandf26e862020-07-01 20:18:19 -07002332 if (mLastHoverWindowHandle != nullptr &&
2333 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2334 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002335 if (DEBUG_HOVER) {
2336 ALOGD("Sending hover exit event to window %s.",
2337 mLastHoverWindowHandle->getName().c_str());
2338 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002339 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002340 InputTarget::Flags::DISPATCH_AS_HOVER_EXIT,
2341 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002342 }
2343
Garfield Tandf26e862020-07-01 20:18:19 -07002344 // Let the new window know that the hover sequence is starting, unless we already did it
2345 // when dispatching it as is to newTouchedWindowHandle.
2346 if (newHoverWindowHandle != nullptr &&
2347 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2348 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002349 if (DEBUG_HOVER) {
2350 ALOGD("Sending hover enter event to window %s.",
2351 newHoverWindowHandle->getName().c_str());
2352 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002353 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002354 InputTarget::Flags::DISPATCH_AS_HOVER_ENTER,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002355 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002356 }
2357 }
2358
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002359 // Ensure that we have at least one foreground window or at least one window that cannot be a
2360 // foreground target. If we only have windows that are not receiving foreground touches (e.g. we
2361 // only have windows getting ACTION_OUTSIDE), then drop the event, because there is no window
2362 // that is actually receiving the entire gesture.
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002363 if (std::none_of(tempTouchState.windows.begin(), tempTouchState.windows.end(),
2364 [](const TouchedWindow& touchedWindow) {
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002365 return !canReceiveForegroundTouches(
2366 *touchedWindow.windowHandle->getInfo()) ||
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002367 touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND);
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002368 })) {
Siarhei Vishniakou1fb18912022-03-08 10:31:39 -08002369 ALOGI("Dropping event because there is no touched window on display %d to receive it: %s",
2370 displayId, entry.getDescription().c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002371 outInjectionResult = InputEventInjectionResult::FAILED;
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002372 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002373 }
2374
Prabir Pradhan5735a322022-04-11 17:23:34 +00002375 // Ensure that all touched windows are valid for injection.
2376 if (entry.injectionState != nullptr) {
2377 std::string errs;
2378 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002379 if (touchedWindow.targetFlags.test(InputTarget::Flags::DISPATCH_AS_OUTSIDE)) {
Prabir Pradhan5735a322022-04-11 17:23:34 +00002380 // Allow ACTION_OUTSIDE events generated by targeted injection to be
2381 // dispatched to any uid, since the coords will be zeroed out later.
2382 continue;
2383 }
2384 const auto err = verifyTargetedInjection(touchedWindow.windowHandle, entry);
2385 if (err) errs += "\n - " + *err;
2386 }
2387 if (!errs.empty()) {
2388 ALOGW("Dropping targeted injection: At least one touched window is not owned by uid "
2389 "%d:%s",
2390 *entry.injectionState->targetUid, errs.c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002391 outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
Prabir Pradhan5735a322022-04-11 17:23:34 +00002392 goto Failed;
2393 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002394 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002395
Michael Wrightd02c5b62014-02-10 15:10:22 -08002396 // Check whether windows listening for outside touches are owned by the same UID. If it is
2397 // set the policy flag that we will not reveal coordinate information to this window.
2398 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002399 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002400 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002401 if (foregroundWindowHandle) {
2402 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002403 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002404 if (touchedWindow.targetFlags.test(InputTarget::Flags::DISPATCH_AS_OUTSIDE)) {
chaviw98318de2021-05-19 16:45:23 -05002405 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2406 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2407 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002408 InputTarget::Flags::ZERO_COORDS,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002409 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002410 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002411 }
2412 }
2413 }
2414 }
2415
Michael Wrightd02c5b62014-02-10 15:10:22 -08002416 // If this is the first pointer going down and the touched window has a wallpaper
2417 // then also add the touched wallpaper windows so they are locked in for the duration
2418 // of the touch gesture.
2419 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2420 // engine only supports touch events. We would need to add a mechanism similar
2421 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2422 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002423 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002424 tempTouchState.getFirstForegroundWindowHandle();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002425 if (foregroundWindowHandle &&
2426 foregroundWindowHandle->getInfo()->inputConfig.test(
2427 WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
chaviw98318de2021-05-19 16:45:23 -05002428 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002429 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002430 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2431 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002432 if (info->displayId == displayId &&
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002433 windowHandle->getInfo()->inputConfig.test(
2434 WindowInfo::InputConfig::IS_WALLPAPER)) {
Arthur Hung74c248d2022-11-23 07:09:59 +00002435 BitSet32 pointerIds;
2436 pointerIds.markBit(entry.pointerProperties[0].id);
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002437 tempTouchState.addOrUpdateWindow(windowHandle,
2438 InputTarget::Flags::WINDOW_IS_OBSCURED |
2439 InputTarget::Flags::
2440 WINDOW_IS_PARTIALLY_OBSCURED |
2441 InputTarget::Flags::DISPATCH_AS_IS,
Arthur Hung74c248d2022-11-23 07:09:59 +00002442 pointerIds, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002443 }
2444 }
2445 }
2446 }
2447
2448 // Success! Output targets.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002449 touchedWindows = tempTouchState.windows;
2450 outInjectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002451
2452 // Drop the outside or hover touch windows since we will not care about them
2453 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002454 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002455
2456Failed:
Michael Wrightd02c5b62014-02-10 15:10:22 -08002457 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002458 if (switchedDevice) {
2459 if (DEBUG_FOCUS) {
2460 ALOGD("Conflicting pointer actions: Switched to a different device.");
2461 }
2462 *outConflictingPointerActions = true;
2463 }
2464
2465 if (isHoverAction) {
2466 // Started hovering, therefore no longer down.
Siarhei Vishniakou3ad385b2022-11-04 10:09:53 -07002467 if (oldState && oldState->isDown()) {
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -08002468 ALOGD_IF(DEBUG_FOCUS,
2469 "Conflicting pointer actions: Hover received while pointer was down.");
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002470 *outConflictingPointerActions = true;
2471 }
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002472 tempTouchState.reset();
2473 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2474 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2475 tempTouchState.deviceId = entry.deviceId;
2476 tempTouchState.source = entry.source;
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002477 }
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002478 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2479 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2480 // All pointers up or canceled.
2481 tempTouchState.reset();
2482 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2483 // First pointer went down.
Siarhei Vishniakou3ad385b2022-11-04 10:09:53 -07002484 if (oldState && oldState->isDown()) {
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -08002485 ALOGD("Conflicting pointer actions: Down received while already down.");
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002486 *outConflictingPointerActions = true;
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002487 }
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002488 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2489 // One pointer went up.
2490 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2491 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002492
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002493 for (size_t i = 0; i < tempTouchState.windows.size();) {
2494 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2495 touchedWindow.pointerIds.clearBit(pointerId);
2496 if (touchedWindow.pointerIds.isEmpty()) {
2497 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2498 continue;
2499 }
2500 i += 1;
2501 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002502 }
2503
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002504 // Save changes unless the action was scroll in which case the temporary touch
2505 // state was only valid for this one action.
2506 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07002507 if (displayId >= 0) {
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002508 mTouchStatesByDisplay[displayId] = tempTouchState;
2509 } else {
2510 mTouchStatesByDisplay.erase(displayId);
2511 }
2512 }
2513
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08002514 if (tempTouchState.windows.empty()) {
2515 mTouchStatesByDisplay.erase(displayId);
2516 }
2517
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002518 // Update hover state.
2519 mLastHoverWindowHandle = newHoverWindowHandle;
2520
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002521 return touchedWindows;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002522}
2523
arthurhung6d4bed92021-03-17 11:59:33 +08002524void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07002525 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2526 // have an explicit reason to support it.
2527 constexpr bool isStylus = false;
2528
chaviw98318de2021-05-19 16:45:23 -05002529 const sp<WindowInfoHandle> dropWindow =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002530 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/, isStylus,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002531 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002532 if (dropWindow) {
2533 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002534 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002535 } else {
Arthur Hung54745652022-04-20 07:17:41 +00002536 ALOGW("No window found when drop.");
Prabir Pradhancef936d2021-07-21 16:17:52 +00002537 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002538 }
2539 mDragState.reset();
2540}
2541
2542void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
Arthur Hung3915c1f2022-05-31 07:17:17 +00002543 if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId) {
arthurhungb89ccb02020-12-30 16:19:01 +08002544 return;
2545 }
2546
arthurhung6d4bed92021-03-17 11:59:33 +08002547 if (!mDragState->isStartDrag) {
2548 mDragState->isStartDrag = true;
2549 mDragState->isStylusButtonDownAtStart =
2550 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2551 }
2552
Arthur Hung54745652022-04-20 07:17:41 +00002553 // Find the pointer index by id.
2554 int32_t pointerIndex = 0;
2555 for (; static_cast<uint32_t>(pointerIndex) < entry.pointerCount; pointerIndex++) {
2556 const PointerProperties& pointerProperties = entry.pointerProperties[pointerIndex];
2557 if (pointerProperties.id == mDragState->pointerId) {
2558 break;
arthurhung6d4bed92021-03-17 11:59:33 +08002559 }
Arthur Hung54745652022-04-20 07:17:41 +00002560 }
arthurhung6d4bed92021-03-17 11:59:33 +08002561
Arthur Hung54745652022-04-20 07:17:41 +00002562 if (uint32_t(pointerIndex) == entry.pointerCount) {
2563 LOG_ALWAYS_FATAL("Should find a valid pointer index by id %d", mDragState->pointerId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002564 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002565 mDragState.reset();
Arthur Hung54745652022-04-20 07:17:41 +00002566 return;
2567 }
2568
2569 const int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2570 const int32_t x = entry.pointerCoords[pointerIndex].getX();
2571 const int32_t y = entry.pointerCoords[pointerIndex].getY();
2572
2573 switch (maskedAction) {
2574 case AMOTION_EVENT_ACTION_MOVE: {
2575 // Handle the special case : stylus button no longer pressed.
2576 bool isStylusButtonDown =
2577 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2578 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2579 finishDragAndDrop(entry.displayId, x, y);
2580 return;
2581 }
2582
2583 // Prevent stylus interceptor windows from affecting drag and drop behavior for now,
2584 // until we have an explicit reason to support it.
2585 constexpr bool isStylus = false;
2586
2587 const sp<WindowInfoHandle> hoverWindowHandle =
2588 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
2589 isStylus, false /*addOutsideTargets*/,
2590 true /*ignoreDragWindow*/);
2591 // enqueue drag exit if needed.
2592 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2593 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2594 if (mDragState->dragHoverWindowHandle != nullptr) {
2595 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/, x,
2596 y);
2597 }
2598 mDragState->dragHoverWindowHandle = hoverWindowHandle;
2599 }
2600 // enqueue drag location if needed.
2601 if (hoverWindowHandle != nullptr) {
2602 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, x, y);
2603 }
2604 break;
2605 }
2606
2607 case AMOTION_EVENT_ACTION_POINTER_UP:
2608 if (getMotionEventActionPointerIndex(entry.action) != pointerIndex) {
2609 break;
2610 }
2611 // The drag pointer is up.
2612 [[fallthrough]];
2613 case AMOTION_EVENT_ACTION_UP:
2614 finishDragAndDrop(entry.displayId, x, y);
2615 break;
2616 case AMOTION_EVENT_ACTION_CANCEL: {
2617 ALOGD("Receiving cancel when drag and drop.");
2618 sendDropWindowCommandLocked(nullptr, 0, 0);
2619 mDragState.reset();
2620 break;
2621 }
arthurhungb89ccb02020-12-30 16:19:01 +08002622 }
2623}
2624
chaviw98318de2021-05-19 16:45:23 -05002625void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002626 ftl::Flags<InputTarget::Flags> targetFlags,
2627 BitSet32 pointerIds,
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002628 std::optional<nsecs_t> firstDownTimeInTarget,
Siarhei Vishniakouf75cddb2022-10-25 10:42:16 -07002629 std::vector<InputTarget>& inputTargets) const {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002630 std::vector<InputTarget>::iterator it =
2631 std::find_if(inputTargets.begin(), inputTargets.end(),
2632 [&windowHandle](const InputTarget& inputTarget) {
2633 return inputTarget.inputChannel->getConnectionToken() ==
2634 windowHandle->getToken();
2635 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002636
chaviw98318de2021-05-19 16:45:23 -05002637 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002638
2639 if (it == inputTargets.end()) {
2640 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002641 std::shared_ptr<InputChannel> inputChannel =
2642 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002643 if (inputChannel == nullptr) {
2644 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2645 return;
2646 }
2647 inputTarget.inputChannel = inputChannel;
2648 inputTarget.flags = targetFlags;
2649 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002650 inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002651 const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
2652 if (displayInfoIt != mDisplayInfos.end()) {
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002653 inputTarget.displayTransform = displayInfoIt->second.transform;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002654 } else {
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00002655 ALOGE("DisplayInfo not found for window on display: %d", windowInfo->displayId);
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002656 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002657 inputTargets.push_back(inputTarget);
2658 it = inputTargets.end() - 1;
2659 }
2660
2661 ALOG_ASSERT(it->flags == targetFlags);
2662 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2663
chaviw1ff3d1e2020-07-01 15:53:47 -07002664 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002665}
2666
Michael Wright3dd60e22019-03-27 22:06:44 +00002667void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002668 int32_t displayId) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002669 auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
2670 if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
Michael Wright3dd60e22019-03-27 22:06:44 +00002671
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002672 for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
2673 InputTarget target;
2674 target.inputChannel = monitor.inputChannel;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002675 target.flags = InputTarget::Flags::DISPATCH_AS_IS;
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002676 // target.firstDownTimeInTarget is not set for global monitors. It is only required in split
2677 // touch and global monitoring works as intended even without setting firstDownTimeInTarget
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002678 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
2679 target.displayTransform = it->second.transform;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002680 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002681 target.setDefaultPointerTransform(target.displayTransform);
2682 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002683 }
2684}
2685
Robert Carrc9bf1d32020-04-13 17:21:08 -07002686/**
2687 * Indicate whether one window handle should be considered as obscuring
2688 * another window handle. We only check a few preconditions. Actually
2689 * checking the bounds is left to the caller.
2690 */
chaviw98318de2021-05-19 16:45:23 -05002691static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2692 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002693 // Compare by token so cloned layers aren't counted
2694 if (haveSameToken(windowHandle, otherHandle)) {
2695 return false;
2696 }
2697 auto info = windowHandle->getInfo();
2698 auto otherInfo = otherHandle->getInfo();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002699 if (otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002700 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002701 } else if (otherInfo->alpha == 0 &&
2702 otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002703 // Those act as if they were invisible, so we don't need to flag them.
2704 // We do want to potentially flag touchable windows even if they have 0
2705 // opacity, since they can consume touches and alter the effects of the
2706 // user interaction (eg. apps that rely on
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002707 // Flags::WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002708 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2709 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002710 } else if (info->ownerUid == otherInfo->ownerUid) {
2711 // If ownerUid is the same we don't generate occlusion events as there
2712 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002713 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002714 } else if (otherInfo->inputConfig.test(gui::WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002715 return false;
2716 } else if (otherInfo->displayId != info->displayId) {
2717 return false;
2718 }
2719 return true;
2720}
2721
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002722/**
2723 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2724 * untrusted, one should check:
2725 *
2726 * 1. If result.hasBlockingOcclusion is true.
2727 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2728 * BLOCK_UNTRUSTED.
2729 *
2730 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2731 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2732 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2733 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2734 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2735 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2736 *
2737 * If neither of those is true, then it means the touch can be allowed.
2738 */
2739InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002740 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2741 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002742 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002743 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002744 TouchOcclusionInfo info;
2745 info.hasBlockingOcclusion = false;
2746 info.obscuringOpacity = 0;
2747 info.obscuringUid = -1;
2748 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002749 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002750 if (windowHandle == otherHandle) {
2751 break; // All future windows are below us. Exit early.
2752 }
chaviw98318de2021-05-19 16:45:23 -05002753 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002754 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2755 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002756 if (DEBUG_TOUCH_OCCLUSION) {
2757 info.debugInfo.push_back(
2758 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2759 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002760 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2761 // we perform the checks below to see if the touch can be propagated or not based on the
2762 // window's touch occlusion mode
2763 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2764 info.hasBlockingOcclusion = true;
2765 info.obscuringUid = otherInfo->ownerUid;
2766 info.obscuringPackage = otherInfo->packageName;
2767 break;
2768 }
2769 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2770 uint32_t uid = otherInfo->ownerUid;
2771 float opacity =
2772 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2773 // Given windows A and B:
2774 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2775 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2776 opacityByUid[uid] = opacity;
2777 if (opacity > info.obscuringOpacity) {
2778 info.obscuringOpacity = opacity;
2779 info.obscuringUid = uid;
2780 info.obscuringPackage = otherInfo->packageName;
2781 }
2782 }
2783 }
2784 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002785 if (DEBUG_TOUCH_OCCLUSION) {
2786 info.debugInfo.push_back(
2787 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2788 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002789 return info;
2790}
2791
chaviw98318de2021-05-19 16:45:23 -05002792std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002793 bool isTouchedWindow) const {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08002794 return StringPrintf(INDENT2 "* %spackage=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2795 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2796 "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
2797 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002798 isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
2799 info->ownerUid, info->id, toString(info->touchOcclusionMode).c_str(),
2800 info->alpha, info->frameLeft, info->frameTop, info->frameRight,
2801 info->frameBottom, dumpRegion(info->touchableRegion).c_str(),
2802 info->name.c_str(), info->inputConfig.string().c_str(),
Prabir Pradhan51e7db02022-02-07 06:02:57 -08002803 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002804 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002805}
2806
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002807bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2808 if (occlusionInfo.hasBlockingOcclusion) {
2809 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2810 occlusionInfo.obscuringUid);
2811 return false;
2812 }
2813 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2814 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2815 "%.2f, maximum allowed = %.2f)",
2816 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2817 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2818 return false;
2819 }
2820 return true;
2821}
2822
chaviw98318de2021-05-19 16:45:23 -05002823bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002824 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002825 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002826 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2827 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002828 if (windowHandle == otherHandle) {
2829 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002830 }
chaviw98318de2021-05-19 16:45:23 -05002831 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002832 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002833 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002834 return true;
2835 }
2836 }
2837 return false;
2838}
2839
chaviw98318de2021-05-19 16:45:23 -05002840bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002841 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002842 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2843 const WindowInfo* windowInfo = windowHandle->getInfo();
2844 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002845 if (windowHandle == otherHandle) {
2846 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002847 }
chaviw98318de2021-05-19 16:45:23 -05002848 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002849 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002850 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002851 return true;
2852 }
2853 }
2854 return false;
2855}
2856
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002857std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002858 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002859 if (applicationHandle != nullptr) {
2860 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002861 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002862 } else {
2863 return applicationHandle->getName();
2864 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002865 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002866 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002867 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002868 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002869 }
2870}
2871
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002872void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00002873 if (!isUserActivityEvent(eventEntry)) {
2874 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002875 return;
2876 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002877 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002878 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002879 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002880 const WindowInfo* info = focusedWindowHandle->getInfo();
Prabir Pradhan51e7db02022-02-07 06:02:57 -08002881 if (info->inputConfig.test(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002882 if (DEBUG_DISPATCH_CYCLE) {
2883 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2884 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002885 return;
2886 }
2887 }
2888
2889 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002890 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002891 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002892 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2893 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002894 return;
2895 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002896
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002897 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002898 eventType = USER_ACTIVITY_EVENT_TOUCH;
2899 }
2900 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002901 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002902 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002903 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2904 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002905 return;
2906 }
2907 eventType = USER_ACTIVITY_EVENT_BUTTON;
2908 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002909 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002910 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002911 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08002912 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002913 break;
2914 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002915 }
2916
Prabir Pradhancef936d2021-07-21 16:17:52 +00002917 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2918 REQUIRES(mLock) {
2919 scoped_unlock unlock(mLock);
2920 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2921 };
2922 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002923}
2924
2925void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002926 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002927 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002928 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002929 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002930 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002931 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002932 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002933 ATRACE_NAME(message.c_str());
2934 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002935 if (DEBUG_DISPATCH_CYCLE) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002936 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=%s, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002937 "globalScaleFactor=%f, pointerIds=0x%x %s",
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002938 connection->getInputChannelName().c_str(), inputTarget.flags.string().c_str(),
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002939 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2940 inputTarget.getPointerInfoString().c_str());
2941 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002942
2943 // Skip this event if the connection status is not normal.
2944 // We don't want to enqueue additional outbound events if the connection is broken.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002945 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002946 if (DEBUG_DISPATCH_CYCLE) {
2947 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002948 connection->getInputChannelName().c_str(),
2949 ftl::enum_string(connection->status).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002950 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002951 return;
2952 }
2953
2954 // Split a motion event if needed.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002955 if (inputTarget.flags.test(InputTarget::Flags::SPLIT)) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002956 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002957 "Entry type %s should not have Flags::SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08002958 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002959
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002960 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002961 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002962 LOG_ALWAYS_FATAL_IF(!inputTarget.firstDownTimeInTarget.has_value(),
2963 "Splitting motion events requires a down time to be set for the "
2964 "target");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002965 std::unique_ptr<MotionEntry> splitMotionEntry =
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002966 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds,
2967 inputTarget.firstDownTimeInTarget.value());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002968 if (!splitMotionEntry) {
2969 return; // split event was dropped
2970 }
Arthur Hungb3307ee2021-10-14 10:57:37 +00002971 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
2972 std::string reason = std::string("reason=pointer cancel on split window");
2973 android_log_event_list(LOGTAG_INPUT_CANCEL)
2974 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
2975 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002976 if (DEBUG_FOCUS) {
2977 ALOGD("channel '%s' ~ Split motion event.",
2978 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002979 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002980 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002981 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2982 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002983 return;
2984 }
2985 }
2986
2987 // Not splitting. Enqueue dispatch entries for the event as is.
2988 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2989}
2990
2991void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002992 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002993 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002994 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002995 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002996 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002997 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002998 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002999 ATRACE_NAME(message.c_str());
3000 }
Siarhei Vishniakou5cee1e32022-11-29 12:35:39 -08003001 LOG_ALWAYS_FATAL_IF(!inputTarget.flags.any(InputTarget::DISPATCH_MASK),
3002 "No dispatch flags are set for %s", eventEntry->getDescription().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003003
hongzuo liu95785e22022-09-06 02:51:35 +00003004 const bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003005
3006 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07003007 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003008 InputTarget::Flags::DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07003009 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003010 InputTarget::Flags::DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07003011 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003012 InputTarget::Flags::DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07003013 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003014 InputTarget::Flags::DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07003015 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003016 InputTarget::Flags::DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07003017 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003018 InputTarget::Flags::DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003019
3020 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003021 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003022 startDispatchCycleLocked(currentTime, connection);
3023 }
3024}
3025
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003026void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003027 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003028 const InputTarget& inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003029 ftl::Flags<InputTarget::Flags> dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003030 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003031 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
3032 connection->getInputChannelName().c_str(),
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003033 dispatchMode.string().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003034 ATRACE_NAME(message.c_str());
3035 }
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003036 ftl::Flags<InputTarget::Flags> inputTargetFlags = inputTarget.flags;
3037 if (!inputTargetFlags.any(dispatchMode)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003038 return;
3039 }
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003040
3041 inputTargetFlags.clear(InputTarget::DISPATCH_MASK);
3042 inputTargetFlags |= dispatchMode;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003043
3044 // This is a new event.
3045 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003046 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003047 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003048
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003049 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
3050 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003051 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003052 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003053 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003054 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003055 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003056 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003057 dispatchEntry->resolvedAction = keyEntry.action;
3058 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003059
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003060 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
3061 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003062 if (DEBUG_DISPATCH_CYCLE) {
3063 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
3064 "event",
3065 connection->getInputChannelName().c_str());
3066 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003067 return; // skip the inconsistent event
3068 }
3069 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003070 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003071
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003072 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003073 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003074 // Assign a default value to dispatchEntry that will never be generated by InputReader,
3075 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
3076 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
3077 static_cast<int32_t>(IdGenerator::Source::OTHER);
3078 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003079 if (dispatchMode.test(InputTarget::Flags::DISPATCH_AS_OUTSIDE)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003080 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003081 } else if (dispatchMode.test(InputTarget::Flags::DISPATCH_AS_HOVER_EXIT)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003082 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003083 } else if (dispatchMode.test(InputTarget::Flags::DISPATCH_AS_HOVER_ENTER)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003084 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003085 } else if (dispatchMode.test(InputTarget::Flags::DISPATCH_AS_SLIPPERY_EXIT)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003086 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003087 } else if (dispatchMode.test(InputTarget::Flags::DISPATCH_AS_SLIPPERY_ENTER)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003088 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
3089 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003090 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003091 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003092 }
3093 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003094 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3095 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003096 if (DEBUG_DISPATCH_CYCLE) {
3097 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
3098 "enter event",
3099 connection->getInputChannelName().c_str());
3100 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003101 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
3102 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003103 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3104 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003105
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003106 dispatchEntry->resolvedFlags = motionEntry.flags;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003107 if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003108 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3109 }
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003110 if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003111 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3112 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003113
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003114 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
3115 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003116 if (DEBUG_DISPATCH_CYCLE) {
3117 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
3118 "event",
3119 connection->getInputChannelName().c_str());
3120 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003121 return; // skip the inconsistent event
3122 }
3123
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003124 dispatchEntry->resolvedEventId =
3125 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
3126 ? mIdGenerator.nextId()
3127 : motionEntry.id;
3128 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
3129 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3130 ") to MotionEvent(id=0x%" PRIx32 ").",
3131 motionEntry.id, dispatchEntry->resolvedEventId);
3132 ATRACE_NAME(message.c_str());
3133 }
3134
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003135 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3136 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
3137 // Skip reporting pointer down outside focus to the policy.
3138 break;
3139 }
3140
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003141 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003142 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003143
3144 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003145 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003146 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003147 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003148 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3149 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003150 break;
3151 }
Chris Yef59a2f42020-10-16 12:55:26 -07003152 case EventEntry::Type::SENSOR: {
3153 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3154 break;
3155 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003156 case EventEntry::Type::CONFIGURATION_CHANGED:
3157 case EventEntry::Type::DEVICE_RESET: {
3158 LOG_ALWAYS_FATAL("%s events should not go to apps",
Dominik Laskowski75788452021-02-09 18:51:25 -08003159 ftl::enum_string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003160 break;
3161 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003162 }
3163
3164 // Remember that we are waiting for this dispatch to complete.
3165 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003166 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003167 }
3168
3169 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003170 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003171 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003172}
3173
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003174/**
3175 * This function is purely for debugging. It helps us understand where the user interaction
3176 * was taking place. For example, if user is touching launcher, we will see a log that user
3177 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3178 * We will see both launcher and wallpaper in that list.
3179 * Once the interaction with a particular set of connections starts, no new logs will be printed
3180 * until the set of interacted connections changes.
3181 *
3182 * The following items are skipped, to reduce the logspam:
3183 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3184 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3185 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3186 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3187 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003188 */
3189void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3190 const std::vector<InputTarget>& targets) {
3191 // Skip ACTION_UP events, and all events other than keys and motions
3192 if (entry.type == EventEntry::Type::KEY) {
3193 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3194 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3195 return;
3196 }
3197 } else if (entry.type == EventEntry::Type::MOTION) {
3198 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3199 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3200 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3201 return;
3202 }
3203 } else {
3204 return; // Not a key or a motion
3205 }
3206
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003207 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003208 std::vector<sp<Connection>> newConnections;
3209 for (const InputTarget& target : targets) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003210 if (target.flags.test(InputTarget::Flags::DISPATCH_AS_OUTSIDE)) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003211 continue; // Skip windows that receive ACTION_OUTSIDE
3212 }
3213
3214 sp<IBinder> token = target.inputChannel->getConnectionToken();
3215 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003216 if (connection == nullptr) {
3217 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003218 }
3219 newConnectionTokens.insert(std::move(token));
3220 newConnections.emplace_back(connection);
3221 }
3222 if (newConnectionTokens == mInteractionConnectionTokens) {
3223 return; // no change
3224 }
3225 mInteractionConnectionTokens = newConnectionTokens;
3226
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003227 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003228 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003229 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003230 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003231 std::string message = "Interaction with: " + targetList;
3232 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003233 message += "<none>";
3234 }
3235 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3236}
3237
chaviwfd6d3512019-03-25 13:23:49 -07003238void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003239 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003240 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003241 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3242 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003243 return;
3244 }
3245
Vishnu Nairc519ff72021-01-21 08:23:08 -08003246 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003247 if (focusedToken == token) {
3248 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003249 return;
3250 }
3251
Prabir Pradhancef936d2021-07-21 16:17:52 +00003252 auto command = [this, token]() REQUIRES(mLock) {
3253 scoped_unlock unlock(mLock);
3254 mPolicy->onPointerDownOutsideFocus(token);
3255 };
3256 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003257}
3258
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003259status_t InputDispatcher::publishMotionEvent(Connection& connection,
3260 DispatchEntry& dispatchEntry) const {
3261 const EventEntry& eventEntry = *(dispatchEntry.eventEntry);
3262 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3263
3264 PointerCoords scaledCoords[MAX_POINTERS];
3265 const PointerCoords* usingCoords = motionEntry.pointerCoords;
3266
3267 // Set the X and Y offset and X and Y scale depending on the input source.
3268 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003269 !(dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS))) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003270 float globalScaleFactor = dispatchEntry.globalScaleFactor;
3271 if (globalScaleFactor != 1.0f) {
3272 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3273 scaledCoords[i] = motionEntry.pointerCoords[i];
3274 // Don't apply window scale here since we don't want scale to affect raw
3275 // coordinates. The scale will be sent back to the client and applied
3276 // later when requesting relative coordinates.
3277 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3278 1 /* windowYScale */);
3279 }
3280 usingCoords = scaledCoords;
3281 }
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003282 } else if (dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS)) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003283 // We don't want the dispatch target to know the coordinates
3284 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3285 scaledCoords[i].clear();
3286 }
3287 usingCoords = scaledCoords;
3288 }
3289
3290 std::array<uint8_t, 32> hmac = getSignature(motionEntry, dispatchEntry);
3291
3292 // Publish the motion event.
3293 return connection.inputPublisher
3294 .publishMotionEvent(dispatchEntry.seq, dispatchEntry.resolvedEventId,
3295 motionEntry.deviceId, motionEntry.source, motionEntry.displayId,
3296 std::move(hmac), dispatchEntry.resolvedAction,
3297 motionEntry.actionButton, dispatchEntry.resolvedFlags,
3298 motionEntry.edgeFlags, motionEntry.metaState,
3299 motionEntry.buttonState, motionEntry.classification,
3300 dispatchEntry.transform, motionEntry.xPrecision,
3301 motionEntry.yPrecision, motionEntry.xCursorPosition,
3302 motionEntry.yCursorPosition, dispatchEntry.rawTransform,
3303 motionEntry.downTime, motionEntry.eventTime,
3304 motionEntry.pointerCount, motionEntry.pointerProperties,
3305 usingCoords);
3306}
3307
Michael Wrightd02c5b62014-02-10 15:10:22 -08003308void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003309 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003310 if (ATRACE_ENABLED()) {
3311 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003312 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003313 ATRACE_NAME(message.c_str());
3314 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003315 if (DEBUG_DISPATCH_CYCLE) {
3316 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3317 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003319 while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003320 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003321 dispatchEntry->deliveryTime = currentTime;
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08003322 const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003323 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003324
3325 // Publish the event.
3326 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003327 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3328 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003329 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003330 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3331 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003332
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003333 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003334 status = connection->inputPublisher
3335 .publishKeyEvent(dispatchEntry->seq,
3336 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3337 keyEntry.source, keyEntry.displayId,
3338 std::move(hmac), dispatchEntry->resolvedAction,
3339 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3340 keyEntry.scanCode, keyEntry.metaState,
3341 keyEntry.repeatCount, keyEntry.downTime,
3342 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003343 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003344 }
3345
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003346 case EventEntry::Type::MOTION: {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003347 status = publishMotionEvent(*connection, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003348 break;
3349 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003350
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003351 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003352 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003353 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003354 focusEntry.id,
Antonio Kantek3cfec7b2021-11-05 18:26:17 -07003355 focusEntry.hasFocus);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003356 break;
3357 }
3358
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003359 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3360 const TouchModeEntry& touchModeEntry =
3361 static_cast<const TouchModeEntry&>(eventEntry);
3362 status = connection->inputPublisher
3363 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3364 touchModeEntry.inTouchMode);
3365
3366 break;
3367 }
3368
Prabir Pradhan99987712020-11-10 18:43:05 -08003369 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3370 const auto& captureEntry =
3371 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3372 status = connection->inputPublisher
3373 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003374 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003375 break;
3376 }
3377
arthurhungb89ccb02020-12-30 16:19:01 +08003378 case EventEntry::Type::DRAG: {
3379 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3380 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3381 dragEntry.id, dragEntry.x,
3382 dragEntry.y,
3383 dragEntry.isExiting);
3384 break;
3385 }
3386
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003387 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003388 case EventEntry::Type::DEVICE_RESET:
3389 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003390 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003391 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003392 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003393 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003394 }
3395
3396 // Check the result.
3397 if (status) {
3398 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003399 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003400 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003401 "This is unexpected because the wait queue is empty, so the pipe "
3402 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003403 "event to it, status=%s(%d)",
3404 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3405 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003406 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3407 } else {
3408 // Pipe is full and we are waiting for the app to finish process some events
3409 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003410 if (DEBUG_DISPATCH_CYCLE) {
3411 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3412 "waiting for the application to catch up",
3413 connection->getInputChannelName().c_str());
3414 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003415 }
3416 } else {
3417 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003418 "status=%s(%d)",
3419 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3420 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003421 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3422 }
3423 return;
3424 }
3425
3426 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003427 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3428 connection->outboundQueue.end(),
3429 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003430 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003431 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003432 if (connection->responsive) {
3433 mAnrTracker.insert(dispatchEntry->timeoutTime,
3434 connection->inputChannel->getConnectionToken());
3435 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003436 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003437 }
3438}
3439
chaviw09c8d2d2020-08-24 15:48:26 -07003440std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3441 size_t size;
3442 switch (event.type) {
3443 case VerifiedInputEvent::Type::KEY: {
3444 size = sizeof(VerifiedKeyEvent);
3445 break;
3446 }
3447 case VerifiedInputEvent::Type::MOTION: {
3448 size = sizeof(VerifiedMotionEvent);
3449 break;
3450 }
3451 }
3452 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3453 return mHmacKeyManager.sign(start, size);
3454}
3455
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003456const std::array<uint8_t, 32> InputDispatcher::getSignature(
3457 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003458 const int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3459 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003460 // Only sign events up and down events as the purely move events
3461 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003462 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003463 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003464
3465 VerifiedMotionEvent verifiedEvent =
3466 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3467 verifiedEvent.actionMasked = actionMasked;
3468 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3469 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003470}
3471
3472const std::array<uint8_t, 32> InputDispatcher::getSignature(
3473 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3474 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3475 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3476 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003477 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003478}
3479
Michael Wrightd02c5b62014-02-10 15:10:22 -08003480void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003481 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003482 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003483 if (DEBUG_DISPATCH_CYCLE) {
3484 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3485 connection->getInputChannelName().c_str(), seq, toString(handled));
3486 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003487
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003488 if (connection->status == Connection::Status::BROKEN ||
3489 connection->status == Connection::Status::ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003490 return;
3491 }
3492
3493 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003494 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3495 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3496 };
3497 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003498}
3499
3500void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003501 const sp<Connection>& connection,
3502 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003503 if (DEBUG_DISPATCH_CYCLE) {
3504 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3505 connection->getInputChannelName().c_str(), toString(notify));
3506 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003507
3508 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003509 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003510 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003511 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003512 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003513
3514 // The connection appears to be unrecoverably broken.
3515 // Ignore already broken or zombie connections.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003516 if (connection->status == Connection::Status::NORMAL) {
3517 connection->status = Connection::Status::BROKEN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003518
3519 if (notify) {
3520 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003521 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3522 connection->getInputChannelName().c_str());
3523
3524 auto command = [this, connection]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003525 scoped_unlock unlock(mLock);
3526 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3527 };
3528 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003529 }
3530 }
3531}
3532
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003533void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3534 while (!queue.empty()) {
3535 DispatchEntry* dispatchEntry = queue.front();
3536 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003537 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003538 }
3539}
3540
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003541void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003542 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003543 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003544 }
3545 delete dispatchEntry;
3546}
3547
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003548int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3549 std::scoped_lock _l(mLock);
3550 sp<Connection> connection = getConnectionLocked(connectionToken);
3551 if (connection == nullptr) {
3552 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3553 connectionToken.get(), events);
3554 return 0; // remove the callback
3555 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003556
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003557 bool notify;
3558 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3559 if (!(events & ALOOPER_EVENT_INPUT)) {
3560 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3561 "events=0x%x",
3562 connection->getInputChannelName().c_str(), events);
3563 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003564 }
3565
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003566 nsecs_t currentTime = now();
3567 bool gotOne = false;
3568 status_t status = OK;
3569 for (;;) {
3570 Result<InputPublisher::ConsumerResponse> result =
3571 connection->inputPublisher.receiveConsumerResponse();
3572 if (!result.ok()) {
3573 status = result.error().code();
3574 break;
3575 }
3576
3577 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3578 const InputPublisher::Finished& finish =
3579 std::get<InputPublisher::Finished>(*result);
3580 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3581 finish.consumeTime);
3582 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003583 if (shouldReportMetricsForConnection(*connection)) {
3584 const InputPublisher::Timeline& timeline =
3585 std::get<InputPublisher::Timeline>(*result);
3586 mLatencyTracker
3587 .trackGraphicsLatency(timeline.inputEventId,
3588 connection->inputChannel->getConnectionToken(),
3589 std::move(timeline.graphicsTimeline));
3590 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003591 }
3592 gotOne = true;
3593 }
3594 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003595 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003596 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003597 return 1;
3598 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003599 }
3600
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003601 notify = status != DEAD_OBJECT || !connection->monitor;
3602 if (notify) {
3603 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3604 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3605 status);
3606 }
3607 } else {
3608 // Monitor channels are never explicitly unregistered.
3609 // We do it automatically when the remote endpoint is closed so don't warn about them.
3610 const bool stillHaveWindowHandle =
3611 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3612 notify = !connection->monitor && stillHaveWindowHandle;
3613 if (notify) {
3614 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3615 connection->getInputChannelName().c_str(), events);
3616 }
3617 }
3618
3619 // Remove the channel.
3620 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3621 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003622}
3623
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003624void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003625 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003626 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003627 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003628 }
3629}
3630
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003631void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003632 const CancelationOptions& options) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08003633 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003634 for (const Monitor& monitor : monitors) {
3635 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003636 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003637 }
3638}
3639
Michael Wrightd02c5b62014-02-10 15:10:22 -08003640void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003641 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003642 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003643 if (connection == nullptr) {
3644 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003645 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003646
3647 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003648}
3649
3650void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3651 const sp<Connection>& connection, const CancelationOptions& options) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003652 if (connection->status == Connection::Status::BROKEN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003653 return;
3654 }
3655
3656 nsecs_t currentTime = now();
3657
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003658 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003659 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003660
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003661 if (cancelationEvents.empty()) {
3662 return;
3663 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003664 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3665 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3666 "with reality: %s, mode=%d.",
3667 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3668 options.mode);
3669 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003670
Arthur Hungb3307ee2021-10-14 10:57:37 +00003671 std::string reason = std::string("reason=").append(options.reason);
3672 android_log_event_list(LOGTAG_INPUT_CANCEL)
3673 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3674
Svet Ganov5d3bc372020-01-26 23:11:07 -08003675 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003676 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003677 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3678 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003679 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003680 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003681 target.globalScaleFactor = windowInfo->globalScaleFactor;
3682 }
3683 target.inputChannel = connection->inputChannel;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003684 target.flags = InputTarget::Flags::DISPATCH_AS_IS;
Svet Ganov5d3bc372020-01-26 23:11:07 -08003685
hongzuo liu95785e22022-09-06 02:51:35 +00003686 const bool wasEmpty = connection->outboundQueue.empty();
3687
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003688 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003689 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003690 switch (cancelationEventEntry->type) {
3691 case EventEntry::Type::KEY: {
3692 logOutboundKeyDetails("cancel - ",
3693 static_cast<const KeyEntry&>(*cancelationEventEntry));
3694 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003695 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003696 case EventEntry::Type::MOTION: {
3697 logOutboundMotionDetails("cancel - ",
3698 static_cast<const MotionEntry&>(*cancelationEventEntry));
3699 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003700 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003701 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003702 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003703 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3704 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003705 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08003706 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003707 break;
3708 }
3709 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003710 case EventEntry::Type::DEVICE_RESET:
3711 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003712 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003713 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003714 break;
3715 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003716 }
3717
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003718 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003719 InputTarget::Flags::DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003720 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003721
hongzuo liu95785e22022-09-06 02:51:35 +00003722 // If the outbound queue was previously empty, start the dispatch cycle going.
3723 if (wasEmpty && !connection->outboundQueue.empty()) {
3724 startDispatchCycleLocked(currentTime, connection);
3725 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003726}
3727
Svet Ganov5d3bc372020-01-26 23:11:07 -08003728void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00003729 const nsecs_t downTime, const sp<Connection>& connection) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003730 if (connection->status == Connection::Status::BROKEN) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003731 return;
3732 }
3733
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003734 std::vector<std::unique_ptr<EventEntry>> downEvents =
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00003735 connection->inputState.synthesizePointerDownEvents(downTime);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003736
3737 if (downEvents.empty()) {
3738 return;
3739 }
3740
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003741 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003742 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3743 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003744 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003745
3746 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003747 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003748 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3749 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003750 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003751 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003752 target.globalScaleFactor = windowInfo->globalScaleFactor;
3753 }
3754 target.inputChannel = connection->inputChannel;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003755 target.flags = InputTarget::Flags::DISPATCH_AS_IS;
Svet Ganov5d3bc372020-01-26 23:11:07 -08003756
hongzuo liu95785e22022-09-06 02:51:35 +00003757 const bool wasEmpty = connection->outboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003758 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003759 switch (downEventEntry->type) {
3760 case EventEntry::Type::MOTION: {
3761 logOutboundMotionDetails("down - ",
3762 static_cast<const MotionEntry&>(*downEventEntry));
3763 break;
3764 }
3765
3766 case EventEntry::Type::KEY:
3767 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003768 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08003769 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003770 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003771 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003772 case EventEntry::Type::SENSOR:
3773 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003774 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003775 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003776 break;
3777 }
3778 }
3779
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003780 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003781 InputTarget::Flags::DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003782 }
3783
hongzuo liu95785e22022-09-06 02:51:35 +00003784 // If the outbound queue was previously empty, start the dispatch cycle going.
3785 if (wasEmpty && !connection->outboundQueue.empty()) {
3786 startDispatchCycleLocked(downTime, connection);
3787 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003788}
3789
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003790std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00003791 const MotionEntry& originalMotionEntry, BitSet32 pointerIds, nsecs_t splitDownTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003792 ALOG_ASSERT(pointerIds.value != 0);
3793
3794 uint32_t splitPointerIndexMap[MAX_POINTERS];
3795 PointerProperties splitPointerProperties[MAX_POINTERS];
3796 PointerCoords splitPointerCoords[MAX_POINTERS];
3797
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003798 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003799 uint32_t splitPointerCount = 0;
3800
3801 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003802 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003803 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003804 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003805 uint32_t pointerId = uint32_t(pointerProperties.id);
3806 if (pointerIds.hasBit(pointerId)) {
3807 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3808 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3809 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003810 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003811 splitPointerCount += 1;
3812 }
3813 }
3814
3815 if (splitPointerCount != pointerIds.count()) {
3816 // This is bad. We are missing some of the pointers that we expected to deliver.
3817 // Most likely this indicates that we received an ACTION_MOVE events that has
3818 // different pointer ids than we expected based on the previous ACTION_DOWN
3819 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3820 // in this way.
3821 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003822 "we expected there to be %d pointers. This probably means we received "
3823 "a broken sequence of pointer ids from the input device.",
3824 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003825 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003826 }
3827
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003828 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003829 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003830 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3831 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003832 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3833 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003834 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003835 uint32_t pointerId = uint32_t(pointerProperties.id);
3836 if (pointerIds.hasBit(pointerId)) {
3837 if (pointerIds.count() == 1) {
3838 // The first/last pointer went down/up.
3839 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003840 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003841 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3842 ? AMOTION_EVENT_ACTION_CANCEL
3843 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003844 } else {
3845 // A secondary pointer went down/up.
3846 uint32_t splitPointerIndex = 0;
3847 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3848 splitPointerIndex += 1;
3849 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003850 action = maskedAction |
3851 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003852 }
3853 } else {
3854 // An unrelated pointer changed.
3855 action = AMOTION_EVENT_ACTION_MOVE;
3856 }
3857 }
3858
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00003859 if (action == AMOTION_EVENT_ACTION_DOWN) {
3860 LOG_ALWAYS_FATAL_IF(splitDownTime != originalMotionEntry.eventTime,
3861 "Split motion event has mismatching downTime and eventTime for "
3862 "ACTION_DOWN, motionEntry=%s, splitDownTime=%" PRId64 "ms",
3863 originalMotionEntry.getDescription().c_str(), ns2ms(splitDownTime));
3864 }
3865
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003866 int32_t newId = mIdGenerator.nextId();
3867 if (ATRACE_ENABLED()) {
3868 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3869 ") to MotionEvent(id=0x%" PRIx32 ").",
3870 originalMotionEntry.id, newId);
3871 ATRACE_NAME(message.c_str());
3872 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003873 std::unique_ptr<MotionEntry> splitMotionEntry =
3874 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3875 originalMotionEntry.deviceId, originalMotionEntry.source,
3876 originalMotionEntry.displayId,
3877 originalMotionEntry.policyFlags, action,
3878 originalMotionEntry.actionButton,
3879 originalMotionEntry.flags, originalMotionEntry.metaState,
3880 originalMotionEntry.buttonState,
3881 originalMotionEntry.classification,
3882 originalMotionEntry.edgeFlags,
3883 originalMotionEntry.xPrecision,
3884 originalMotionEntry.yPrecision,
3885 originalMotionEntry.xCursorPosition,
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00003886 originalMotionEntry.yCursorPosition, splitDownTime,
3887 splitPointerCount, splitPointerProperties,
3888 splitPointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003889
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003890 if (originalMotionEntry.injectionState) {
3891 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003892 splitMotionEntry->injectionState->refCount += 1;
3893 }
3894
3895 return splitMotionEntry;
3896}
3897
3898void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003899 if (DEBUG_INBOUND_EVENT_DETAILS) {
3900 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3901 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003902
Antonio Kantekf16f2832021-09-28 04:39:20 +00003903 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003904 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003905 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003906
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003907 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3908 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3909 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003910 } // release lock
3911
3912 if (needWake) {
3913 mLooper->wake();
3914 }
3915}
3916
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003917/**
3918 * If one of the meta shortcuts is detected, process them here:
3919 * Meta + Backspace -> generate BACK
3920 * Meta + Enter -> generate HOME
3921 * This will potentially overwrite keyCode and metaState.
3922 */
3923void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003924 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003925 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3926 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3927 if (keyCode == AKEYCODE_DEL) {
3928 newKeyCode = AKEYCODE_BACK;
3929 } else if (keyCode == AKEYCODE_ENTER) {
3930 newKeyCode = AKEYCODE_HOME;
3931 }
3932 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003933 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003934 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003935 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003936 keyCode = newKeyCode;
3937 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3938 }
3939 } else if (action == AKEY_EVENT_ACTION_UP) {
3940 // In order to maintain a consistent stream of up and down events, check to see if the key
3941 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3942 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003943 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003944 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003945 auto replacementIt = mReplacedKeys.find(replacement);
3946 if (replacementIt != mReplacedKeys.end()) {
3947 keyCode = replacementIt->second;
3948 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003949 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3950 }
3951 }
3952}
3953
Michael Wrightd02c5b62014-02-10 15:10:22 -08003954void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003955 if (DEBUG_INBOUND_EVENT_DETAILS) {
3956 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3957 "policyFlags=0x%x, action=0x%x, "
3958 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3959 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3960 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3961 args->downTime);
3962 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003963 if (!validateKeyEvent(args->action)) {
3964 return;
3965 }
3966
3967 uint32_t policyFlags = args->policyFlags;
3968 int32_t flags = args->flags;
3969 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003970 // InputDispatcher tracks and generates key repeats on behalf of
3971 // whatever notifies it, so repeatCount should always be set to 0
3972 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003973 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3974 policyFlags |= POLICY_FLAG_VIRTUAL;
3975 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3976 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003977 if (policyFlags & POLICY_FLAG_FUNCTION) {
3978 metaState |= AMETA_FUNCTION_ON;
3979 }
3980
3981 policyFlags |= POLICY_FLAG_TRUSTED;
3982
Michael Wright78f24442014-08-06 15:55:28 -07003983 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003984 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003985
Michael Wrightd02c5b62014-02-10 15:10:22 -08003986 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003987 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003988 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3989 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003990
Michael Wright2b3c3302018-03-02 17:19:13 +00003991 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003992 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003993 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3994 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003995 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003996 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003997
Antonio Kantekf16f2832021-09-28 04:39:20 +00003998 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003999 { // acquire lock
4000 mLock.lock();
4001
4002 if (shouldSendKeyToInputFilterLocked(args)) {
4003 mLock.unlock();
4004
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004005 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004006 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
4007 return; // event was consumed by the filter
4008 }
4009
4010 mLock.lock();
4011 }
4012
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004013 std::unique_ptr<KeyEntry> newEntry =
4014 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
4015 args->displayId, policyFlags, args->action, flags,
4016 keyCode, args->scanCode, metaState, repeatCount,
4017 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004018
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004019 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004020 mLock.unlock();
4021 } // release lock
4022
4023 if (needWake) {
4024 mLooper->wake();
4025 }
4026}
4027
4028bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
4029 return mInputFilterEnabled;
4030}
4031
4032void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004033 if (DEBUG_INBOUND_EVENT_DETAILS) {
4034 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4035 "displayId=%" PRId32 ", policyFlags=0x%x, "
Siarhei Vishniakou6ebd0692022-10-20 15:05:45 -07004036 "action=%s, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004037 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
4038 "yCursorPosition=%f, downTime=%" PRId64,
4039 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
Siarhei Vishniakou6ebd0692022-10-20 15:05:45 -07004040 args->policyFlags, MotionEvent::actionToString(args->action).c_str(),
4041 args->actionButton, args->flags, args->metaState, args->buttonState, args->edgeFlags,
4042 args->xPrecision, args->yPrecision, args->xCursorPosition, args->yCursorPosition,
4043 args->downTime);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004044 for (uint32_t i = 0; i < args->pointerCount; i++) {
4045 ALOGD(" Pointer %d: id=%d, toolType=%d, "
4046 "x=%f, y=%f, pressure=%f, size=%f, "
4047 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
4048 "orientation=%f",
4049 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
4050 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
4051 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
4052 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
4053 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
4054 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
4055 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
4056 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
4057 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
4058 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
4059 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004060 }
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -08004061 LOG_ALWAYS_FATAL_IF(!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
4062 args->pointerProperties),
4063 "Invalid event: %s", args->dump().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004064
4065 uint32_t policyFlags = args->policyFlags;
4066 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004067
4068 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08004069 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004070 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4071 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004072 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004073 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004074
Antonio Kantekf16f2832021-09-28 04:39:20 +00004075 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004076 { // acquire lock
4077 mLock.lock();
4078
4079 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004080 ui::Transform displayTransform;
4081 if (const auto it = mDisplayInfos.find(args->displayId); it != mDisplayInfos.end()) {
4082 displayTransform = it->second.transform;
4083 }
4084
Michael Wrightd02c5b62014-02-10 15:10:22 -08004085 mLock.unlock();
4086
4087 MotionEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08004088 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
4089 args->action, args->actionButton, args->flags, args->edgeFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07004090 args->metaState, args->buttonState, args->classification,
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004091 displayTransform, args->xPrecision, args->yPrecision,
4092 args->xCursorPosition, args->yCursorPosition, displayTransform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07004093 args->downTime, args->eventTime, args->pointerCount,
4094 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004095
4096 policyFlags |= POLICY_FLAG_FILTERED;
4097 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
4098 return; // event was consumed by the filter
4099 }
4100
4101 mLock.lock();
4102 }
4103
4104 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004105 std::unique_ptr<MotionEntry> newEntry =
4106 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
4107 args->source, args->displayId, policyFlags,
4108 args->action, args->actionButton, args->flags,
4109 args->metaState, args->buttonState,
4110 args->classification, args->edgeFlags,
4111 args->xPrecision, args->yPrecision,
4112 args->xCursorPosition, args->yCursorPosition,
4113 args->downTime, args->pointerCount,
Prabir Pradhan5beda762021-12-10 09:30:08 +00004114 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004115
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004116 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4117 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
4118 !mInputFilterEnabled) {
4119 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
4120 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
4121 }
4122
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004123 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004124 mLock.unlock();
4125 } // release lock
4126
4127 if (needWake) {
4128 mLooper->wake();
4129 }
4130}
4131
Chris Yef59a2f42020-10-16 12:55:26 -07004132void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004133 if (DEBUG_INBOUND_EVENT_DETAILS) {
4134 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4135 " sensorType=%s",
4136 args->id, args->eventTime, args->deviceId, args->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08004137 ftl::enum_string(args->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004138 }
Chris Yef59a2f42020-10-16 12:55:26 -07004139
Antonio Kantekf16f2832021-09-28 04:39:20 +00004140 bool needWake = false;
Chris Yef59a2f42020-10-16 12:55:26 -07004141 { // acquire lock
4142 mLock.lock();
4143
4144 // Just enqueue a new sensor event.
4145 std::unique_ptr<SensorEntry> newEntry =
4146 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
4147 args->source, 0 /* policyFlags*/, args->hwTimestamp,
4148 args->sensorType, args->accuracy,
4149 args->accuracyChanged, args->values);
4150
4151 needWake = enqueueInboundEventLocked(std::move(newEntry));
4152 mLock.unlock();
4153 } // release lock
4154
4155 if (needWake) {
4156 mLooper->wake();
4157 }
4158}
4159
Chris Yefb552902021-02-03 17:18:37 -08004160void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004161 if (DEBUG_INBOUND_EVENT_DETAILS) {
4162 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
4163 args->deviceId, args->isOn);
4164 }
Chris Yefb552902021-02-03 17:18:37 -08004165 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
4166}
4167
Michael Wrightd02c5b62014-02-10 15:10:22 -08004168bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08004169 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004170}
4171
4172void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004173 if (DEBUG_INBOUND_EVENT_DETAILS) {
4174 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4175 "switchMask=0x%08x",
4176 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
4177 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004178
4179 uint32_t policyFlags = args->policyFlags;
4180 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004181 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004182}
4183
4184void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004185 if (DEBUG_INBOUND_EVENT_DETAILS) {
4186 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
4187 args->deviceId);
4188 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004189
Antonio Kantekf16f2832021-09-28 04:39:20 +00004190 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004191 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004192 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004193
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004194 std::unique_ptr<DeviceResetEntry> newEntry =
4195 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
4196 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004197 } // release lock
4198
4199 if (needWake) {
4200 mLooper->wake();
4201 }
4202}
4203
Prabir Pradhan7e186182020-11-10 13:56:45 -08004204void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004205 if (DEBUG_INBOUND_EVENT_DETAILS) {
4206 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004207 args->request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004208 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004209
Antonio Kantekf16f2832021-09-28 04:39:20 +00004210 bool needWake = false;
Prabir Pradhan99987712020-11-10 18:43:05 -08004211 { // acquire lock
4212 std::scoped_lock _l(mLock);
4213 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004214 args->request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004215 needWake = enqueueInboundEventLocked(std::move(entry));
4216 } // release lock
4217
4218 if (needWake) {
4219 mLooper->wake();
4220 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004221}
4222
Prabir Pradhan5735a322022-04-11 17:23:34 +00004223InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* event,
4224 std::optional<int32_t> targetUid,
4225 InputEventInjectionSync syncMode,
4226 std::chrono::milliseconds timeout,
4227 uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004228 if (DEBUG_INBOUND_EVENT_DETAILS) {
Prabir Pradhan5735a322022-04-11 17:23:34 +00004229 ALOGD("injectInputEvent - eventType=%d, targetUid=%s, syncMode=%d, timeout=%lld, "
4230 "policyFlags=0x%08x",
4231 event->getType(), targetUid ? std::to_string(*targetUid).c_str() : "none", syncMode,
4232 timeout.count(), policyFlags);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004233 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004234 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004235
Prabir Pradhan5735a322022-04-11 17:23:34 +00004236 policyFlags |= POLICY_FLAG_INJECTED | POLICY_FLAG_TRUSTED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004237
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004238 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004239 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4240 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4241 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4242 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4243 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004244 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004245 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004246 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004247 }
4248
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004249 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004250 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004251 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004252 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4253 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004254 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004255 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004256 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004257
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004258 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004259 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4260 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4261 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004262 int32_t keyCode = incomingKey.getKeyCode();
4263 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004264 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004265 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004266 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004267 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004268 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4269 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4270 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004271
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004272 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4273 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004274 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004275
4276 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4277 android::base::Timer t;
4278 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4279 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4280 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4281 std::to_string(t.duration().count()).c_str());
4282 }
4283 }
4284
4285 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004286 std::unique_ptr<KeyEntry> injectedEntry =
4287 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004288 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004289 incomingKey.getDisplayId(), policyFlags, action,
4290 flags, keyCode, incomingKey.getScanCode(), metaState,
4291 incomingKey.getRepeatCount(),
4292 incomingKey.getDownTime());
4293 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004294 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004295 }
4296
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004297 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004298 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004299 const int32_t action = motionEvent.getAction();
4300 const bool isPointerEvent =
4301 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4302 // If a pointer event has no displayId specified, inject it to the default display.
4303 const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
4304 ? ADISPLAY_ID_DEFAULT
4305 : event->getDisplayId();
4306 const size_t pointerCount = motionEvent.getPointerCount();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004307 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004308 const int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004309 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004310 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004311 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004312 }
4313
4314 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004315 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004316 android::base::Timer t;
4317 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4318 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4319 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4320 std::to_string(t.duration().count()).c_str());
4321 }
4322 }
4323
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004324 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4325 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4326 }
4327
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004328 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004329 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4330 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004331 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004332 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4333 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004334 displayId, policyFlags, action, actionButton,
4335 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004336 motionEvent.getButtonState(),
4337 motionEvent.getClassification(),
4338 motionEvent.getEdgeFlags(),
4339 motionEvent.getXPrecision(),
4340 motionEvent.getYPrecision(),
4341 motionEvent.getRawXCursorPosition(),
4342 motionEvent.getRawYCursorPosition(),
4343 motionEvent.getDownTime(), uint32_t(pointerCount),
Prabir Pradhan5beda762021-12-10 09:30:08 +00004344 pointerProperties, samplePointerCoords);
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004345 transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004346 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004347 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004348 sampleEventTimes += 1;
4349 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004350 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004351 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4352 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004353 displayId, policyFlags, action, actionButton,
4354 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004355 motionEvent.getButtonState(),
4356 motionEvent.getClassification(),
4357 motionEvent.getEdgeFlags(),
4358 motionEvent.getXPrecision(),
4359 motionEvent.getYPrecision(),
4360 motionEvent.getRawXCursorPosition(),
4361 motionEvent.getRawYCursorPosition(),
4362 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004363 uint32_t(pointerCount), pointerProperties,
Prabir Pradhan5beda762021-12-10 09:30:08 +00004364 samplePointerCoords);
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004365 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
4366 motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004367 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004368 }
4369 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004370 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004371
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004372 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004373 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004374 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004375 }
4376
Prabir Pradhan5735a322022-04-11 17:23:34 +00004377 InjectionState* injectionState = new InjectionState(targetUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004378 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004379 injectionState->injectionIsAsync = true;
4380 }
4381
4382 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004383 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004384
4385 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004386 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004387 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004388 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004389 }
4390
4391 mLock.unlock();
4392
4393 if (needWake) {
4394 mLooper->wake();
4395 }
4396
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004397 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004398 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004399 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004400
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004401 if (syncMode == InputEventInjectionSync::NONE) {
4402 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004403 } else {
4404 for (;;) {
4405 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004406 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004407 break;
4408 }
4409
4410 nsecs_t remainingTimeout = endTime - now();
4411 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004412 if (DEBUG_INJECTION) {
4413 ALOGD("injectInputEvent - Timed out waiting for injection result "
4414 "to become available.");
4415 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004416 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004417 break;
4418 }
4419
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004420 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004421 }
4422
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004423 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4424 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004425 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004426 if (DEBUG_INJECTION) {
4427 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4428 injectionState->pendingForegroundDispatches);
4429 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004430 nsecs_t remainingTimeout = endTime - now();
4431 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004432 if (DEBUG_INJECTION) {
4433 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4434 "dispatches to finish.");
4435 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004436 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004437 break;
4438 }
4439
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004440 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004441 }
4442 }
4443 }
4444
4445 injectionState->release();
4446 } // release lock
4447
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004448 if (DEBUG_INJECTION) {
Prabir Pradhan5735a322022-04-11 17:23:34 +00004449 ALOGD("injectInputEvent - Finished with result %d.", injectionResult);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004450 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004451
4452 return injectionResult;
4453}
4454
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004455std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004456 std::array<uint8_t, 32> calculatedHmac;
4457 std::unique_ptr<VerifiedInputEvent> result;
4458 switch (event.getType()) {
4459 case AINPUT_EVENT_TYPE_KEY: {
4460 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4461 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4462 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004463 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004464 break;
4465 }
4466 case AINPUT_EVENT_TYPE_MOTION: {
4467 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4468 VerifiedMotionEvent verifiedMotionEvent =
4469 verifiedMotionEventFromMotionEvent(motionEvent);
4470 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004471 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004472 break;
4473 }
4474 default: {
4475 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4476 return nullptr;
4477 }
4478 }
4479 if (calculatedHmac == INVALID_HMAC) {
4480 return nullptr;
4481 }
4482 if (calculatedHmac != event.getHmac()) {
4483 return nullptr;
4484 }
4485 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004486}
4487
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004488void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004489 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004490 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004491 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004492 if (DEBUG_INJECTION) {
Prabir Pradhan5735a322022-04-11 17:23:34 +00004493 ALOGD("Setting input event injection result to %d.", injectionResult);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004494 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004495
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004496 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004497 // Log the outcome since the injector did not wait for the injection result.
4498 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004499 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004500 ALOGV("Asynchronous input event injection succeeded.");
4501 break;
Prabir Pradhan5735a322022-04-11 17:23:34 +00004502 case InputEventInjectionResult::TARGET_MISMATCH:
4503 ALOGV("Asynchronous input event injection target mismatch.");
4504 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004505 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004506 ALOGW("Asynchronous input event injection failed.");
4507 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004508 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004509 ALOGW("Asynchronous input event injection timed out.");
4510 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004511 case InputEventInjectionResult::PENDING:
4512 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4513 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004514 }
4515 }
4516
4517 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004518 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004519 }
4520}
4521
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004522void InputDispatcher::transformMotionEntryForInjectionLocked(
4523 MotionEntry& entry, const ui::Transform& injectedTransform) const {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004524 // Input injection works in the logical display coordinate space, but the input pipeline works
4525 // display space, so we need to transform the injected events accordingly.
4526 const auto it = mDisplayInfos.find(entry.displayId);
4527 if (it == mDisplayInfos.end()) return;
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004528 const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004529
Prabir Pradhand9a2ebe2022-07-20 19:25:13 +00004530 if (entry.xCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
4531 entry.yCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
4532 const vec2 cursor =
4533 MotionEvent::calculateTransformedXY(entry.source, transformToDisplay,
4534 {entry.xCursorPosition, entry.yCursorPosition});
4535 entry.xCursorPosition = cursor.x;
4536 entry.yCursorPosition = cursor.y;
4537 }
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004538 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Prabir Pradhan8e6ce222022-02-24 09:08:54 -08004539 entry.pointerCoords[i] =
4540 MotionEvent::calculateTransformedCoords(entry.source, transformToDisplay,
4541 entry.pointerCoords[i]);
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004542 }
4543}
4544
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004545void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4546 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004547 if (injectionState) {
4548 injectionState->pendingForegroundDispatches += 1;
4549 }
4550}
4551
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004552void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4553 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004554 if (injectionState) {
4555 injectionState->pendingForegroundDispatches -= 1;
4556
4557 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004558 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004559 }
4560 }
4561}
4562
chaviw98318de2021-05-19 16:45:23 -05004563const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004564 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004565 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004566 auto it = mWindowHandlesByDisplay.find(displayId);
4567 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004568}
4569
chaviw98318de2021-05-19 16:45:23 -05004570sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004571 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004572 if (windowHandleToken == nullptr) {
4573 return nullptr;
4574 }
4575
Arthur Hungb92218b2018-08-14 12:00:21 +08004576 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004577 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4578 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004579 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004580 return windowHandle;
4581 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004582 }
4583 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004584 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004585}
4586
chaviw98318de2021-05-19 16:45:23 -05004587sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4588 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004589 if (windowHandleToken == nullptr) {
4590 return nullptr;
4591 }
4592
chaviw98318de2021-05-19 16:45:23 -05004593 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004594 if (windowHandle->getToken() == windowHandleToken) {
4595 return windowHandle;
4596 }
4597 }
4598 return nullptr;
4599}
4600
chaviw98318de2021-05-19 16:45:23 -05004601sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4602 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004603 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004604 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4605 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004606 if (handle->getId() == windowHandle->getId() &&
4607 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004608 if (windowHandle->getInfo()->displayId != it.first) {
4609 ALOGE("Found window %s in display %" PRId32
4610 ", but it should belong to display %" PRId32,
4611 windowHandle->getName().c_str(), it.first,
4612 windowHandle->getInfo()->displayId);
4613 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004614 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004615 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004616 }
4617 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004618 return nullptr;
4619}
4620
chaviw98318de2021-05-19 16:45:23 -05004621sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004622 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4623 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004624}
4625
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07004626bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& window,
4627 const MotionEntry& motionEntry) const {
4628 const WindowInfo& info = *window->getInfo();
4629
4630 // Skip spy window targets that are not valid for targeted injection.
4631 if (const auto err = verifyTargetedInjection(window, motionEntry); err) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004632 return false;
4633 }
4634
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07004635 if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
4636 ALOGI("Not sending touch event to %s because it is paused", window->getName().c_str());
4637 return false;
4638 }
4639
4640 if (info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL)) {
4641 ALOGW("Not sending touch gesture to %s because it has config NO_INPUT_CHANNEL",
4642 window->getName().c_str());
4643 return false;
4644 }
4645
4646 sp<Connection> connection = getConnectionLocked(window->getToken());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004647 if (connection == nullptr) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07004648 ALOGW("Not sending touch to %s because there's no corresponding connection",
4649 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004650 return false;
4651 }
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07004652
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004653 if (!connection->responsive) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07004654 ALOGW("Not sending touch to %s because it is not responsive", window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004655 return false;
4656 }
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07004657
4658 // Drop events that can't be trusted due to occlusion
4659 const auto [x, y] = resolveTouchedPosition(motionEntry);
4660 TouchOcclusionInfo occlusionInfo = computeTouchOcclusionInfoLocked(window, x, y);
4661 if (!isTouchTrustedLocked(occlusionInfo)) {
4662 if (DEBUG_TOUCH_OCCLUSION) {
4663 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
4664 for (const auto& log : occlusionInfo.debugInfo) {
4665 ALOGD("%s", log.c_str());
4666 }
4667 }
4668 ALOGW("Dropping untrusted touch event due to %s/%d", occlusionInfo.obscuringPackage.c_str(),
4669 occlusionInfo.obscuringUid);
4670 return false;
4671 }
4672
4673 // Drop touch events if requested by input feature
4674 if (shouldDropInput(motionEntry, window)) {
4675 return false;
4676 }
4677
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004678 return true;
4679}
4680
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004681std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4682 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004683 auto connectionIt = mConnectionsByToken.find(token);
4684 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004685 return nullptr;
4686 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004687 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004688}
4689
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004690void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004691 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4692 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004693 // Remove all handles on a display if there are no windows left.
4694 mWindowHandlesByDisplay.erase(displayId);
4695 return;
4696 }
4697
4698 // Since we compare the pointer of input window handles across window updates, we need
4699 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004700 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4701 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4702 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004703 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004704 }
4705
chaviw98318de2021-05-19 16:45:23 -05004706 std::vector<sp<WindowInfoHandle>> newHandles;
4707 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05004708 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004709 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004710 const bool noInputChannel =
Prabir Pradhan51e7db02022-02-07 06:02:57 -08004711 info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08004712 const bool canReceiveInput =
4713 !info->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) ||
4714 !info->inputConfig.test(WindowInfo::InputConfig::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004715 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004716 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004717 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004718 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004719 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004720 }
4721
4722 if (info->displayId != displayId) {
4723 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4724 handle->getName().c_str(), displayId, info->displayId);
4725 continue;
4726 }
4727
Robert Carredd13602020-04-13 17:24:34 -07004728 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4729 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004730 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004731 oldHandle->updateFrom(handle);
4732 newHandles.push_back(oldHandle);
4733 } else {
4734 newHandles.push_back(handle);
4735 }
4736 }
4737
4738 // Insert or replace
4739 mWindowHandlesByDisplay[displayId] = newHandles;
4740}
4741
Arthur Hung72d8dc32020-03-28 00:48:39 +00004742void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004743 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07004744 // TODO(b/198444055): Remove setInputWindows from InputDispatcher.
Arthur Hung72d8dc32020-03-28 00:48:39 +00004745 { // acquire lock
4746 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004747 for (const auto& [displayId, handles] : handlesPerDisplay) {
4748 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004749 }
4750 }
4751 // Wake up poll loop since it may need to make new input dispatching choices.
4752 mLooper->wake();
4753}
4754
Arthur Hungb92218b2018-08-14 12:00:21 +08004755/**
4756 * Called from InputManagerService, update window handle list by displayId that can receive input.
4757 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4758 * If set an empty list, remove all handles from the specific display.
4759 * For focused handle, check if need to change and send a cancel event to previous one.
4760 * For removed handle, check if need to send a cancel event if already in touch.
4761 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004762void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004763 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004764 if (DEBUG_FOCUS) {
4765 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004766 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004767 windowList += iwh->getName() + " ";
4768 }
4769 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4770 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004771
Prabir Pradhand65552b2021-10-07 11:23:50 -07004772 // Check preconditions for new input windows
chaviw98318de2021-05-19 16:45:23 -05004773 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07004774 const WindowInfo& info = *window->getInfo();
4775
4776 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
Prabir Pradhan51e7db02022-02-07 06:02:57 -08004777 const bool noInputWindow = info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004778 if (noInputWindow && window->getToken() != nullptr) {
4779 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4780 window->getName().c_str());
4781 window->releaseChannel();
4782 }
Prabir Pradhand65552b2021-10-07 11:23:50 -07004783
Prabir Pradhan5c85e052021-12-22 02:27:12 -08004784 // Ensure all spy windows are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08004785 LOG_ALWAYS_FATAL_IF(info.isSpy() &&
4786 !info.inputConfig.test(
4787 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhan5c85e052021-12-22 02:27:12 -08004788 "%s has feature SPY, but is not a trusted overlay.",
4789 window->getName().c_str());
4790
Prabir Pradhand65552b2021-10-07 11:23:50 -07004791 // Ensure all stylus interceptors are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08004792 LOG_ALWAYS_FATAL_IF(info.interceptsStylus() &&
4793 !info.inputConfig.test(
4794 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhand65552b2021-10-07 11:23:50 -07004795 "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
4796 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004797 }
4798
Arthur Hung72d8dc32020-03-28 00:48:39 +00004799 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004800 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004801
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004802 // Save the old windows' orientation by ID before it gets updated.
4803 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004804 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004805 oldWindowOrientations.emplace(handle->getId(),
4806 handle->getInfo()->transform.getOrientation());
4807 }
4808
chaviw98318de2021-05-19 16:45:23 -05004809 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004810
chaviw98318de2021-05-19 16:45:23 -05004811 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Tommy Nordgrendae9dfc2022-10-13 11:25:57 +02004812 if (mLastHoverWindowHandle) {
4813 const WindowInfo* lastHoverWindowInfo = mLastHoverWindowHandle->getInfo();
4814 if (lastHoverWindowInfo->displayId == displayId &&
4815 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4816 windowHandles.end()) {
4817 mLastHoverWindowHandle = nullptr;
4818 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004819 }
4820
Vishnu Nairc519ff72021-01-21 08:23:08 -08004821 std::optional<FocusResolver::FocusChanges> changes =
4822 mFocusResolver.setInputWindows(displayId, windowHandles);
4823 if (changes) {
4824 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004825 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004826
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004827 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4828 mTouchStatesByDisplay.find(displayId);
4829 if (stateIt != mTouchStatesByDisplay.end()) {
4830 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004831 for (size_t i = 0; i < state.windows.size();) {
4832 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004833 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004834 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004835 ALOGD("Touched window was removed: %s in display %" PRId32,
4836 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004837 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004838 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004839 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4840 if (touchedInputChannel != nullptr) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00004841 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Arthur Hung72d8dc32020-03-28 00:48:39 +00004842 "touched window was removed");
4843 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004844 // Since we are about to drop the touch, cancel the events for the wallpaper as
4845 // well.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08004846 if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08004847 touchedWindow.windowHandle->getInfo()->inputConfig.test(
4848 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004849 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
4850 if (wallpaper != nullptr) {
4851 sp<Connection> wallpaperConnection =
4852 getConnectionLocked(wallpaper->getToken());
Siarhei Vishniakou2b030972021-11-18 10:01:27 -08004853 if (wallpaperConnection != nullptr) {
4854 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection,
4855 options);
4856 }
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004857 }
4858 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004859 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004860 state.windows.erase(state.windows.begin() + i);
4861 } else {
4862 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004863 }
4864 }
arthurhungb89ccb02020-12-30 16:19:01 +08004865
arthurhung6d4bed92021-03-17 11:59:33 +08004866 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004867 // could just clear the state here.
Arthur Hung3915c1f2022-05-31 07:17:17 +00004868 if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId &&
arthurhung6d4bed92021-03-17 11:59:33 +08004869 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004870 windowHandles.end()) {
Arthur Hung3915c1f2022-05-31 07:17:17 +00004871 ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str());
4872 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08004873 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004874 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004875 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004876
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00004877 // Determine if the orientation of any of the input windows have changed, and cancel all
4878 // pointer events if necessary.
4879 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4880 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
4881 if (newWindowHandle != nullptr &&
4882 newWindowHandle->getInfo()->transform.getOrientation() !=
4883 oldWindowOrientations[oldWindowHandle->getId()]) {
4884 std::shared_ptr<InputChannel> inputChannel =
4885 getInputChannelLocked(newWindowHandle->getToken());
4886 if (inputChannel != nullptr) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00004887 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00004888 "touched window's orientation changed");
4889 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004890 }
4891 }
4892 }
4893
Arthur Hung72d8dc32020-03-28 00:48:39 +00004894 // Release information for windows that are no longer present.
4895 // This ensures that unused input channels are released promptly.
4896 // Otherwise, they might stick around until the window handle is destroyed
4897 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004898 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004899 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004900 if (DEBUG_FOCUS) {
4901 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004902 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004903 oldWindowHandle->releaseChannel();
Arthur Hung25e2af12020-03-26 12:58:37 +00004904 }
chaviw291d88a2019-02-14 10:33:58 -08004905 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004906}
4907
4908void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004909 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004910 if (DEBUG_FOCUS) {
4911 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4912 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4913 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004914 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004915 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004916 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004917 } // release lock
4918
4919 // Wake up poll loop since it may need to make new input dispatching choices.
4920 mLooper->wake();
4921}
4922
Vishnu Nair599f1412021-06-21 10:39:58 -07004923void InputDispatcher::setFocusedApplicationLocked(
4924 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4925 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4926 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4927
4928 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4929 return; // This application is already focused. No need to wake up or change anything.
4930 }
4931
4932 // Set the new application handle.
4933 if (inputApplicationHandle != nullptr) {
4934 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4935 } else {
4936 mFocusedApplicationHandlesByDisplay.erase(displayId);
4937 }
4938
4939 // No matter what the old focused application was, stop waiting on it because it is
4940 // no longer focused.
4941 resetNoFocusedWindowTimeoutLocked();
4942}
4943
Tiger Huang721e26f2018-07-24 22:26:19 +08004944/**
4945 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4946 * the display not specified.
4947 *
4948 * We track any unreleased events for each window. If a window loses the ability to receive the
4949 * released event, we will send a cancel event to it. So when the focused display is changed, we
4950 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4951 * display. The display-specified events won't be affected.
4952 */
4953void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004954 if (DEBUG_FOCUS) {
4955 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4956 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004957 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004958 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004959
4960 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004961 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004962 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004963 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004964 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004965 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004966 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004967 CancelationOptions
Michael Wrightfb04fd52022-11-24 22:31:11 +00004968 options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004969 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004970 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004971 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4972 }
4973 }
4974 mFocusedDisplayId = displayId;
4975
Chris Ye3c2d6f52020-08-09 10:39:48 -07004976 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004977 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004978 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004979
Vishnu Nairad321cd2020-08-20 16:40:21 -07004980 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004981 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004982 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004983 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004984 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004985 }
4986 }
4987 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004988 } // release lock
4989
4990 // Wake up poll loop since it may need to make new input dispatching choices.
4991 mLooper->wake();
4992}
4993
Michael Wrightd02c5b62014-02-10 15:10:22 -08004994void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004995 if (DEBUG_FOCUS) {
4996 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4997 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004998
4999 bool changed;
5000 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005001 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005002
5003 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
5004 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005005 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005006 }
5007
5008 if (mDispatchEnabled && !enabled) {
5009 resetAndDropEverythingLocked("dispatcher is being disabled");
5010 }
5011
5012 mDispatchEnabled = enabled;
5013 mDispatchFrozen = frozen;
5014 changed = true;
5015 } else {
5016 changed = false;
5017 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005018 } // release lock
5019
5020 if (changed) {
5021 // Wake up poll loop since it may need to make new input dispatching choices.
5022 mLooper->wake();
5023 }
5024}
5025
5026void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005027 if (DEBUG_FOCUS) {
5028 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
5029 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005030
5031 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005032 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005033
5034 if (mInputFilterEnabled == enabled) {
5035 return;
5036 }
5037
5038 mInputFilterEnabled = enabled;
5039 resetAndDropEverythingLocked("input filter is being enabled or disabled");
5040 } // release lock
5041
5042 // Wake up poll loop since there might be work to do to drop everything.
5043 mLooper->wake();
5044}
5045
Antonio Kanteka042c022022-07-06 16:51:07 -07005046bool InputDispatcher::setInTouchMode(bool inTouchMode, int32_t pid, int32_t uid, bool hasPermission,
5047 int32_t displayId) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00005048 bool needWake = false;
5049 {
5050 std::scoped_lock lock(mLock);
Antonio Kantek15beb512022-06-13 22:35:41 +00005051 ALOGD_IF(DEBUG_TOUCH_MODE,
5052 "Request to change touch mode to %s (calling pid=%d, uid=%d, "
5053 "hasPermission=%s, target displayId=%d, mTouchModePerDisplay[displayId]=%s)",
5054 toString(inTouchMode), pid, uid, toString(hasPermission), displayId,
5055 mTouchModePerDisplay.count(displayId) == 0
5056 ? "not set"
5057 : std::to_string(mTouchModePerDisplay[displayId]).c_str());
5058
Antonio Kantek15beb512022-06-13 22:35:41 +00005059 auto touchModeIt = mTouchModePerDisplay.find(displayId);
5060 if (touchModeIt != mTouchModePerDisplay.end() && touchModeIt->second == inTouchMode) {
Antonio Kantekea47acb2021-12-23 12:41:25 -08005061 return false;
Antonio Kantekf16f2832021-09-28 04:39:20 +00005062 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005063 if (!hasPermission) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005064 if (!focusedWindowIsOwnedByLocked(pid, uid) &&
5065 !recentWindowsAreOwnedByLocked(pid, uid)) {
5066 ALOGD("Touch mode switch rejected, caller (pid=%d, uid=%d) doesn't own the focused "
5067 "window nor none of the previously interacted window",
5068 pid, uid);
Antonio Kantekea47acb2021-12-23 12:41:25 -08005069 return false;
5070 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00005071 }
Antonio Kantek15beb512022-06-13 22:35:41 +00005072 mTouchModePerDisplay[displayId] = inTouchMode;
5073 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode,
5074 displayId);
Antonio Kantekf16f2832021-09-28 04:39:20 +00005075 needWake = enqueueInboundEventLocked(std::move(entry));
5076 } // release lock
5077
5078 if (needWake) {
5079 mLooper->wake();
5080 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005081 return true;
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08005082}
5083
Antonio Kantek48710e42022-03-24 14:19:30 -07005084bool InputDispatcher::focusedWindowIsOwnedByLocked(int32_t pid, int32_t uid) {
5085 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
5086 if (focusedToken == nullptr) {
5087 return false;
5088 }
5089 sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken);
5090 return isWindowOwnedBy(windowHandle, pid, uid);
5091}
5092
5093bool InputDispatcher::recentWindowsAreOwnedByLocked(int32_t pid, int32_t uid) {
5094 return std::find_if(mInteractionConnectionTokens.begin(), mInteractionConnectionTokens.end(),
5095 [&](const sp<IBinder>& connectionToken) REQUIRES(mLock) {
5096 const sp<WindowInfoHandle> windowHandle =
5097 getWindowHandleLocked(connectionToken);
5098 return isWindowOwnedBy(windowHandle, pid, uid);
5099 }) != mInteractionConnectionTokens.end();
5100}
5101
Bernardo Rufinoea97d182020-08-19 14:43:14 +01005102void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
5103 if (opacity < 0 || opacity > 1) {
5104 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
5105 return;
5106 }
5107
5108 std::scoped_lock lock(mLock);
5109 mMaximumObscuringOpacityForTouch = opacity;
5110}
5111
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005112std::tuple<TouchState*, TouchedWindow*, int32_t /*displayId*/>
5113InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) {
Arthur Hungabbb9d82021-09-01 14:52:30 +00005114 for (auto& [displayId, state] : mTouchStatesByDisplay) {
5115 for (TouchedWindow& w : state.windows) {
5116 if (w.windowHandle->getToken() == token) {
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005117 return std::make_tuple(&state, &w, displayId);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005118 }
5119 }
5120 }
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005121 return std::make_tuple(nullptr, nullptr, ADISPLAY_ID_DEFAULT);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005122}
5123
arthurhungb89ccb02020-12-30 16:19:01 +08005124bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5125 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08005126 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005127 if (DEBUG_FOCUS) {
5128 ALOGD("Trivial transfer to same window.");
5129 }
chaviwfbe5d9c2018-12-26 12:23:37 -08005130 return true;
5131 }
5132
Michael Wrightd02c5b62014-02-10 15:10:22 -08005133 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005134 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005135
Arthur Hungabbb9d82021-09-01 14:52:30 +00005136 // Find the target touch state and touched window by fromToken.
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005137 auto [state, touchedWindow, displayId] = findTouchStateWindowAndDisplayLocked(fromToken);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005138 if (state == nullptr || touchedWindow == nullptr) {
5139 ALOGD("Focus transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005140 return false;
5141 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00005142
Arthur Hungabbb9d82021-09-01 14:52:30 +00005143 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
5144 if (toWindowHandle == nullptr) {
5145 ALOGW("Cannot transfer focus because to window not found.");
5146 return false;
5147 }
5148
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005149 if (DEBUG_FOCUS) {
5150 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00005151 touchedWindow->windowHandle->getName().c_str(),
5152 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005153 }
5154
Arthur Hungabbb9d82021-09-01 14:52:30 +00005155 // Erase old window.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005156 ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags;
Arthur Hungabbb9d82021-09-01 14:52:30 +00005157 BitSet32 pointerIds = touchedWindow->pointerIds;
5158 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005159
Arthur Hungabbb9d82021-09-01 14:52:30 +00005160 // Add new window.
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00005161 nsecs_t downTimeInTarget = now();
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005162 ftl::Flags<InputTarget::Flags> newTargetFlags =
5163 oldTargetFlags & (InputTarget::Flags::SPLIT | InputTarget::Flags::DISPATCH_AS_IS);
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005164 if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005165 newTargetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005166 }
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00005167 state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds, downTimeInTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005168
Arthur Hungabbb9d82021-09-01 14:52:30 +00005169 // Store the dragging window.
5170 if (isDragDrop) {
Arthur Hungb75c2aa2022-07-15 09:35:36 +00005171 if (pointerIds.count() != 1) {
5172 ALOGW("The drag and drop cannot be started when there is no pointer or more than 1"
5173 " pointer on the window.");
Arthur Hung54745652022-04-20 07:17:41 +00005174 return false;
5175 }
Arthur Hungb75c2aa2022-07-15 09:35:36 +00005176 // Track the pointer id for drag window and generate the drag state.
5177 const int32_t id = pointerIds.firstMarkedBit();
Arthur Hung54745652022-04-20 07:17:41 +00005178 mDragState = std::make_unique<DragState>(toWindowHandle, id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005179 }
5180
Arthur Hungabbb9d82021-09-01 14:52:30 +00005181 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005182 sp<Connection> fromConnection = getConnectionLocked(fromToken);
5183 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005184 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005185 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005186 CancelationOptions
Michael Wrightfb04fd52022-11-24 22:31:11 +00005187 options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005188 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005189 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00005190 synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005191 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005192 } // release lock
5193
5194 // Wake up poll loop since it may need to make new input dispatching choices.
5195 mLooper->wake();
5196 return true;
5197}
5198
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005199/**
5200 * Get the touched foreground window on the given display.
5201 * Return null if there are no windows touched on that display, or if more than one foreground
5202 * window is being touched.
5203 */
5204sp<WindowInfoHandle> InputDispatcher::findTouchedForegroundWindowLocked(int32_t displayId) const {
5205 auto stateIt = mTouchStatesByDisplay.find(displayId);
5206 if (stateIt == mTouchStatesByDisplay.end()) {
5207 ALOGI("No touch state on display %" PRId32, displayId);
5208 return nullptr;
5209 }
5210
5211 const TouchState& state = stateIt->second;
5212 sp<WindowInfoHandle> touchedForegroundWindow;
5213 // If multiple foreground windows are touched, return nullptr
5214 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005215 if (window.targetFlags.test(InputTarget::Flags::FOREGROUND)) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005216 if (touchedForegroundWindow != nullptr) {
5217 ALOGI("Two or more foreground windows: %s and %s",
5218 touchedForegroundWindow->getName().c_str(),
5219 window.windowHandle->getName().c_str());
5220 return nullptr;
5221 }
5222 touchedForegroundWindow = window.windowHandle;
5223 }
5224 }
5225 return touchedForegroundWindow;
5226}
5227
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005228// Binder call
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005229bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken, int32_t displayId) {
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005230 sp<IBinder> fromToken;
5231 { // acquire lock
5232 std::scoped_lock _l(mLock);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005233 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005234 if (toWindowHandle == nullptr) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005235 ALOGW("Could not find window associated with token=%p on display %" PRId32,
5236 destChannelToken.get(), displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005237 return false;
5238 }
5239
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005240 sp<WindowInfoHandle> from = findTouchedForegroundWindowLocked(displayId);
5241 if (from == nullptr) {
5242 ALOGE("Could not find a source window in %s for %p", __func__, destChannelToken.get());
5243 return false;
5244 }
5245
5246 fromToken = from->getToken();
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005247 } // release lock
5248
5249 return transferTouchFocus(fromToken, destChannelToken);
5250}
5251
Michael Wrightd02c5b62014-02-10 15:10:22 -08005252void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005253 if (DEBUG_FOCUS) {
5254 ALOGD("Resetting and dropping all events (%s).", reason);
5255 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005256
Michael Wrightfb04fd52022-11-24 22:31:11 +00005257 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005258 synthesizeCancelationEventsForAllConnectionsLocked(options);
5259
5260 resetKeyRepeatLocked();
5261 releasePendingEventLocked();
5262 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005263 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005264
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005265 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005266 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005267 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07005268 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005269}
5270
5271void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005272 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005273 dumpDispatchStateLocked(dump);
5274
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005275 std::istringstream stream(dump);
5276 std::string line;
5277
5278 while (std::getline(stream, line, '\n')) {
5279 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005280 }
5281}
5282
Prabir Pradhan99987712020-11-10 18:43:05 -08005283std::string InputDispatcher::dumpPointerCaptureStateLocked() {
5284 std::string dump;
5285
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005286 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5287 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005288
5289 std::string windowName = "None";
5290 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005291 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005292 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5293 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5294 : "token has capture without window";
5295 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005296 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005297
5298 return dump;
5299}
5300
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005301void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005302 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5303 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5304 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005305 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005306
Tiger Huang721e26f2018-07-24 22:26:19 +08005307 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5308 dump += StringPrintf(INDENT "FocusedApplications:\n");
5309 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5310 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005311 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005312 const std::chrono::duration timeout =
5313 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005314 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005315 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005316 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005317 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005318 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005319 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005320 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005321
Vishnu Nairc519ff72021-01-21 08:23:08 -08005322 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005323 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005324
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005325 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005326 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005327 for (const auto& [displayId, state] : mTouchStatesByDisplay) {
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -08005328 std::string touchStateDump = addLinePrefix(state.dump(), INDENT2);
5329 dump += INDENT2 + std::to_string(displayId) + " : " + touchStateDump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005330 }
5331 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005332 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005333 }
5334
arthurhung6d4bed92021-03-17 11:59:33 +08005335 if (mDragState) {
5336 dump += StringPrintf(INDENT "DragState:\n");
5337 mDragState->dump(dump, INDENT2);
5338 }
5339
Arthur Hungb92218b2018-08-14 12:00:21 +08005340 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005341 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5342 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5343 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5344 const auto& displayInfo = it->second;
5345 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5346 displayInfo.logicalHeight);
5347 displayInfo.transform.dump(dump, "transform", INDENT4);
5348 } else {
5349 dump += INDENT2 "No DisplayInfo found!\n";
5350 }
5351
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005352 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005353 dump += INDENT2 "Windows:\n";
5354 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005355 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5356 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005357
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005358 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005359 "inputConfig=%s, alpha=%.2f, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005360 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005361 "applicationInfo.name=%s, "
5362 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005363 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005364 i, windowInfo->name.c_str(), windowInfo->id,
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005365 windowInfo->displayId,
5366 windowInfo->inputConfig.string().c_str(),
5367 windowInfo->alpha, windowInfo->frameLeft,
5368 windowInfo->frameTop, windowInfo->frameRight,
5369 windowInfo->frameBottom, windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005370 windowInfo->applicationInfo.name.c_str(),
5371 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005372 dump += dumpRegion(windowInfo->touchableRegion);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005373 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005374 "ms, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005375 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005376 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005377 millis(windowInfo->dispatchingTimeout),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005378 toString(windowInfo->token != nullptr),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005379 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005380 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005381 }
5382 } else {
5383 dump += INDENT2 "Windows: <none>\n";
5384 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005385 }
5386 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005387 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005388 }
5389
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005390 if (!mGlobalMonitorsByDisplay.empty()) {
5391 for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
5392 dump += StringPrintf(INDENT "Global monitors on display %d:\n", displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00005393 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005394 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005395 } else {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005396 dump += INDENT "Global Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005397 }
5398
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005399 const nsecs_t currentTime = now();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005400
5401 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005402 if (!mRecentQueue.empty()) {
5403 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005404 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005405 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005406 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005407 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005408 }
5409 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005410 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005411 }
5412
5413 // Dump event currently being dispatched.
5414 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005415 dump += INDENT "PendingEvent:\n";
5416 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005417 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005418 dump += StringPrintf(", age=%" PRId64 "ms\n",
5419 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005420 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005421 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005422 }
5423
5424 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005425 if (!mInboundQueue.empty()) {
5426 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005427 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005428 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005429 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005430 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005431 }
5432 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005433 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005434 }
5435
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005436 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005437 dump += INDENT "ReplacedKeys:\n";
Michael Wright3cec4462022-11-24 22:05:46 +00005438 for (const auto& [replacement, newKeyCode] : mReplacedKeys) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005439 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005440 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005441 }
5442 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005443 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005444 }
5445
Prabir Pradhancef936d2021-07-21 16:17:52 +00005446 if (!mCommandQueue.empty()) {
5447 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5448 } else {
5449 dump += INDENT "CommandQueue: <empty>\n";
5450 }
5451
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005452 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005453 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005454 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005455 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005456 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005457 connection->inputChannel->getFd().get(),
5458 connection->getInputChannelName().c_str(),
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005459 connection->getWindowName().c_str(),
5460 ftl::enum_string(connection->status).c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005461 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005462
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005463 if (!connection->outboundQueue.empty()) {
5464 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5465 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005466 dump += dumpQueue(connection->outboundQueue, currentTime);
5467
Michael Wrightd02c5b62014-02-10 15:10:22 -08005468 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005469 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005470 }
5471
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005472 if (!connection->waitQueue.empty()) {
5473 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5474 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005475 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005476 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005477 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005478 }
5479 }
5480 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005481 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005482 }
5483
5484 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005485 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5486 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005487 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005488 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005489 }
5490
Antonio Kantek15beb512022-06-13 22:35:41 +00005491 if (!mTouchModePerDisplay.empty()) {
5492 dump += INDENT "TouchModePerDisplay:\n";
5493 for (const auto& [displayId, touchMode] : mTouchModePerDisplay) {
5494 dump += StringPrintf(INDENT2 "Display: %" PRId32 " TouchMode: %s\n", displayId,
5495 std::to_string(touchMode).c_str());
5496 }
5497 } else {
5498 dump += INDENT "TouchModePerDisplay: <none>\n";
5499 }
5500
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005501 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005502 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5503 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5504 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005505 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005506 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005507}
5508
Michael Wright3dd60e22019-03-27 22:06:44 +00005509void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5510 const size_t numMonitors = monitors.size();
5511 for (size_t i = 0; i < numMonitors; i++) {
5512 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005513 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005514 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5515 dump += "\n";
5516 }
5517}
5518
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005519class LooperEventCallback : public LooperCallback {
5520public:
5521 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5522 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5523
5524private:
5525 std::function<int(int events)> mCallback;
5526};
5527
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005528Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005529 if (DEBUG_CHANNEL_CREATION) {
5530 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5531 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005532
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005533 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005534 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005535 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005536
5537 if (result) {
5538 return base::Error(result) << "Failed to open input channel pair with name " << name;
5539 }
5540
Michael Wrightd02c5b62014-02-10 15:10:22 -08005541 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005542 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005543 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005544 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005545 sp<Connection> connection =
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005546 sp<Connection>::make(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005547
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005548 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5549 ALOGE("Created a new connection, but the token %p is already known", token.get());
5550 }
5551 mConnectionsByToken.emplace(token, connection);
5552
5553 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5554 this, std::placeholders::_1, token);
5555
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005556 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
5557 nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005558 } // release lock
5559
5560 // Wake the looper because some connections have changed.
5561 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005562 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005563}
5564
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005565Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005566 const std::string& name,
5567 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005568 std::shared_ptr<InputChannel> serverChannel;
5569 std::unique_ptr<InputChannel> clientChannel;
5570 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5571 if (result) {
5572 return base::Error(result) << "Failed to open input channel pair with name " << name;
5573 }
5574
Michael Wright3dd60e22019-03-27 22:06:44 +00005575 { // acquire lock
5576 std::scoped_lock _l(mLock);
5577
5578 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005579 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5580 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005581 }
5582
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005583 sp<Connection> connection =
5584 sp<Connection>::make(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005585 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005586 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005587
5588 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5589 ALOGE("Created a new connection, but the token %p is already known", token.get());
5590 }
5591 mConnectionsByToken.emplace(token, connection);
5592 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5593 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005594
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005595 mGlobalMonitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005596
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005597 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
5598 nullptr);
Michael Wright3dd60e22019-03-27 22:06:44 +00005599 }
Garfield Tan15601662020-09-22 15:32:38 -07005600
Michael Wright3dd60e22019-03-27 22:06:44 +00005601 // Wake the looper because some connections have changed.
5602 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005603 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005604}
5605
Garfield Tan15601662020-09-22 15:32:38 -07005606status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005607 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005608 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005609
Garfield Tan15601662020-09-22 15:32:38 -07005610 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005611 if (status) {
5612 return status;
5613 }
5614 } // release lock
5615
5616 // Wake the poll loop because removing the connection may have changed the current
5617 // synchronization state.
5618 mLooper->wake();
5619 return OK;
5620}
5621
Garfield Tan15601662020-09-22 15:32:38 -07005622status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5623 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005624 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005625 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005626 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005627 return BAD_VALUE;
5628 }
5629
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005630 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005631
Michael Wrightd02c5b62014-02-10 15:10:22 -08005632 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005633 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005634 }
5635
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005636 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005637
5638 nsecs_t currentTime = now();
5639 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5640
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005641 connection->status = Connection::Status::ZOMBIE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005642 return OK;
5643}
5644
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005645void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005646 for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
5647 auto& [displayId, monitors] = *it;
5648 std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
5649 return monitor.inputChannel->getConnectionToken() == connectionToken;
5650 });
Michael Wright3dd60e22019-03-27 22:06:44 +00005651
Michael Wright3dd60e22019-03-27 22:06:44 +00005652 if (monitors.empty()) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005653 it = mGlobalMonitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005654 } else {
5655 ++it;
5656 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005657 }
5658}
5659
Michael Wright3dd60e22019-03-27 22:06:44 +00005660status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005661 std::scoped_lock _l(mLock);
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00005662 return pilferPointersLocked(token);
5663}
Michael Wright3dd60e22019-03-27 22:06:44 +00005664
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00005665status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005666 const std::shared_ptr<InputChannel> requestingChannel = getInputChannelLocked(token);
5667 if (!requestingChannel) {
5668 ALOGW("Attempted to pilfer pointers from an un-registered channel or invalid token");
5669 return BAD_VALUE;
Michael Wright3dd60e22019-03-27 22:06:44 +00005670 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005671
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005672 auto [statePtr, windowPtr, displayId] = findTouchStateWindowAndDisplayLocked(token);
Siarhei Vishniakou3ad385b2022-11-04 10:09:53 -07005673 if (statePtr == nullptr || windowPtr == nullptr || windowPtr->pointerIds.isEmpty()) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005674 ALOGW("Attempted to pilfer points from a channel without any on-going pointer streams."
5675 " Ignoring.");
5676 return BAD_VALUE;
5677 }
5678
5679 TouchState& state = *statePtr;
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00005680 TouchedWindow& window = *windowPtr;
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005681 // Send cancel events to all the input channels we're stealing from.
Michael Wrightfb04fd52022-11-24 22:31:11 +00005682 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005683 "input channel stole pointer stream");
5684 options.deviceId = state.deviceId;
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005685 options.displayId = displayId;
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07005686 options.pointerIds = window.pointerIds;
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005687 std::string canceledWindows;
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00005688 for (const TouchedWindow& w : state.windows) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005689 const std::shared_ptr<InputChannel> channel =
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00005690 getInputChannelLocked(w.windowHandle->getToken());
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005691 if (channel != nullptr && channel->getConnectionToken() != token) {
5692 synthesizeCancelationEventsForInputChannelLocked(channel, options);
5693 canceledWindows += canceledWindows.empty() ? "[" : ", ";
5694 canceledWindows += channel->getName();
5695 }
5696 }
5697 canceledWindows += canceledWindows.empty() ? "[]" : "]";
5698 ALOGI("Channel %s is stealing touch from %s", requestingChannel->getName().c_str(),
5699 canceledWindows.c_str());
5700
Prabir Pradhane680f9b2022-02-04 04:24:00 -08005701 // Prevent the gesture from being sent to any other windows.
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00005702 // This only blocks relevant pointers to be sent to other windows
5703 window.isPilferingPointers = true;
5704
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07005705 state.cancelPointersForWindowsExcept(window.pointerIds, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005706 return OK;
5707}
5708
Prabir Pradhan99987712020-11-10 18:43:05 -08005709void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5710 { // acquire lock
5711 std::scoped_lock _l(mLock);
5712 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005713 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005714 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5715 windowHandle != nullptr ? windowHandle->getName().c_str()
5716 : "token without window");
5717 }
5718
Vishnu Nairc519ff72021-01-21 08:23:08 -08005719 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005720 if (focusedToken != windowToken) {
5721 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5722 enabled ? "enable" : "disable");
5723 return;
5724 }
5725
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005726 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08005727 ALOGW("Ignoring request to %s Pointer Capture: "
5728 "window has %s requested pointer capture.",
5729 enabled ? "enable" : "disable", enabled ? "already" : "not");
5730 return;
5731 }
5732
Christine Franksb768bb42021-11-29 12:11:31 -08005733 if (enabled) {
5734 if (std::find(mIneligibleDisplaysForPointerCapture.begin(),
5735 mIneligibleDisplaysForPointerCapture.end(),
5736 mFocusedDisplayId) != mIneligibleDisplaysForPointerCapture.end()) {
5737 ALOGW("Ignoring request to enable Pointer Capture: display is not eligible");
5738 return;
5739 }
5740 }
5741
Prabir Pradhan99987712020-11-10 18:43:05 -08005742 setPointerCaptureLocked(enabled);
5743 } // release lock
5744
5745 // Wake the thread to process command entries.
5746 mLooper->wake();
5747}
5748
Christine Franksb768bb42021-11-29 12:11:31 -08005749void InputDispatcher::setDisplayEligibilityForPointerCapture(int32_t displayId, bool isEligible) {
5750 { // acquire lock
5751 std::scoped_lock _l(mLock);
5752 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
5753 if (!isEligible) {
5754 mIneligibleDisplaysForPointerCapture.push_back(displayId);
5755 }
5756 } // release lock
5757}
5758
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005759std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5760 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005761 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005762 if (monitor.inputChannel->getConnectionToken() == token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005763 return monitor.pid;
Michael Wright3dd60e22019-03-27 22:06:44 +00005764 }
5765 }
5766 }
5767 return std::nullopt;
5768}
5769
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005770sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005771 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005772 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005773 }
5774
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005775 for (const auto& [token, connection] : mConnectionsByToken) {
5776 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005777 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005778 }
5779 }
Robert Carr4e670e52018-08-15 13:26:12 -07005780
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005781 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005782}
5783
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005784std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5785 sp<Connection> connection = getConnectionLocked(connectionToken);
5786 if (connection == nullptr) {
5787 return "<nullptr>";
5788 }
5789 return connection->getInputChannelName();
5790}
5791
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005792void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005793 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005794 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005795}
5796
Prabir Pradhancef936d2021-07-21 16:17:52 +00005797void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5798 const sp<Connection>& connection, uint32_t seq,
5799 bool handled, nsecs_t consumeTime) {
5800 // Handle post-event policy actions.
5801 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5802 if (dispatchEntryIt == connection->waitQueue.end()) {
5803 return;
5804 }
5805 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5806 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5807 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5808 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5809 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5810 }
5811 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5812 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5813 connection->inputChannel->getConnectionToken(),
5814 dispatchEntry->deliveryTime, consumeTime, finishTime);
5815 }
5816
5817 bool restartEvent;
5818 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5819 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5820 restartEvent =
5821 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5822 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5823 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5824 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5825 handled);
5826 } else {
5827 restartEvent = false;
5828 }
5829
5830 // Dequeue the event and start the next cycle.
5831 // Because the lock might have been released, it is possible that the
5832 // contents of the wait queue to have been drained, so we need to double-check
5833 // a few things.
5834 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5835 if (dispatchEntryIt != connection->waitQueue.end()) {
5836 dispatchEntry = *dispatchEntryIt;
5837 connection->waitQueue.erase(dispatchEntryIt);
5838 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5839 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5840 if (!connection->responsive) {
5841 connection->responsive = isConnectionResponsive(*connection);
5842 if (connection->responsive) {
5843 // The connection was unresponsive, and now it's responsive.
5844 processConnectionResponsiveLocked(*connection);
5845 }
5846 }
5847 traceWaitQueueLength(*connection);
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005848 if (restartEvent && connection->status == Connection::Status::NORMAL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005849 connection->outboundQueue.push_front(dispatchEntry);
5850 traceOutboundQueueLength(*connection);
5851 } else {
5852 releaseDispatchEntry(dispatchEntry);
5853 }
5854 }
5855
5856 // Start the next dispatch cycle for this connection.
5857 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005858}
5859
Prabir Pradhancef936d2021-07-21 16:17:52 +00005860void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5861 const sp<IBinder>& newToken) {
5862 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5863 scoped_unlock unlock(mLock);
5864 mPolicy->notifyFocusChanged(oldToken, newToken);
5865 };
5866 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005867}
5868
Prabir Pradhancef936d2021-07-21 16:17:52 +00005869void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5870 auto command = [this, token, x, y]() REQUIRES(mLock) {
5871 scoped_unlock unlock(mLock);
5872 mPolicy->notifyDropWindow(token, x, y);
5873 };
5874 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005875}
5876
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005877void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5878 if (connection == nullptr) {
5879 LOG_ALWAYS_FATAL("Caller must check for nullness");
5880 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005881 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5882 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005883 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005884 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005885 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005886 return;
5887 }
5888 /**
5889 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5890 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5891 * has changed. This could cause newer entries to time out before the already dispatched
5892 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5893 * processes the events linearly. So providing information about the oldest entry seems to be
5894 * most useful.
5895 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005896 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005897 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5898 std::string reason =
5899 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005900 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005901 ns2ms(currentWait),
5902 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005903 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005904 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005905
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005906 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5907
5908 // Stop waking up for events on this connection, it is already unresponsive
5909 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005910}
5911
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005912void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5913 std::string reason =
5914 StringPrintf("%s does not have a focused window", application->getName().c_str());
5915 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005916
Prabir Pradhancef936d2021-07-21 16:17:52 +00005917 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5918 scoped_unlock unlock(mLock);
5919 mPolicy->notifyNoFocusedWindowAnr(application);
5920 };
5921 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005922}
5923
chaviw98318de2021-05-19 16:45:23 -05005924void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005925 const std::string& reason) {
5926 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5927 updateLastAnrStateLocked(windowLabel, reason);
5928}
5929
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005930void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5931 const std::string& reason) {
5932 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005933 updateLastAnrStateLocked(windowLabel, reason);
5934}
5935
5936void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5937 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005938 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005939 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005940 struct tm tm;
5941 localtime_r(&t, &tm);
5942 char timestr[64];
5943 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005944 mLastAnrState.clear();
5945 mLastAnrState += INDENT "ANR:\n";
5946 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005947 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5948 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005949 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005950}
5951
Prabir Pradhancef936d2021-07-21 16:17:52 +00005952void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5953 KeyEntry& entry) {
5954 const KeyEvent event = createKeyEvent(entry);
5955 nsecs_t delay = 0;
5956 { // release lock
5957 scoped_unlock unlock(mLock);
5958 android::base::Timer t;
5959 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5960 entry.policyFlags);
5961 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5962 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5963 std::to_string(t.duration().count()).c_str());
5964 }
5965 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005966
5967 if (delay < 0) {
Michael Wright5caf55a2022-11-24 22:31:42 +00005968 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005969 } else if (delay == 0) {
Michael Wright5caf55a2022-11-24 22:31:42 +00005970 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005971 } else {
Michael Wright5caf55a2022-11-24 22:31:42 +00005972 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005973 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005974 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005975}
5976
Prabir Pradhancef936d2021-07-21 16:17:52 +00005977void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhanedd96402022-02-15 01:46:16 -08005978 std::optional<int32_t> pid,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005979 std::string reason) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08005980 auto command = [this, token, pid, reason = std::move(reason)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005981 scoped_unlock unlock(mLock);
Prabir Pradhanedd96402022-02-15 01:46:16 -08005982 mPolicy->notifyWindowUnresponsive(token, pid, reason);
Prabir Pradhancef936d2021-07-21 16:17:52 +00005983 };
5984 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005985}
5986
Prabir Pradhanedd96402022-02-15 01:46:16 -08005987void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& token,
5988 std::optional<int32_t> pid) {
5989 auto command = [this, token, pid]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005990 scoped_unlock unlock(mLock);
Prabir Pradhanedd96402022-02-15 01:46:16 -08005991 mPolicy->notifyWindowResponsive(token, pid);
Prabir Pradhancef936d2021-07-21 16:17:52 +00005992 };
5993 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005994}
5995
5996/**
5997 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5998 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5999 * command entry to the command queue.
6000 */
6001void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
6002 std::string reason) {
6003 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanedd96402022-02-15 01:46:16 -08006004 std::optional<int32_t> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006005 if (connection.monitor) {
6006 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
6007 reason.c_str());
Prabir Pradhanedd96402022-02-15 01:46:16 -08006008 pid = findMonitorPidByTokenLocked(connectionToken);
6009 } else {
6010 // The connection is a window
6011 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
6012 reason.c_str());
6013 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6014 if (handle != nullptr) {
6015 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006016 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006017 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08006018 sendWindowUnresponsiveCommandLocked(connectionToken, pid, std::move(reason));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006019}
6020
6021/**
6022 * Tell the policy that a connection has become responsive so that it can stop ANR.
6023 */
6024void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
6025 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanedd96402022-02-15 01:46:16 -08006026 std::optional<int32_t> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006027 if (connection.monitor) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08006028 pid = findMonitorPidByTokenLocked(connectionToken);
6029 } else {
6030 // The connection is a window
6031 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6032 if (handle != nullptr) {
6033 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006034 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006035 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08006036 sendWindowResponsiveCommandLocked(connectionToken, pid);
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006037}
6038
Prabir Pradhancef936d2021-07-21 16:17:52 +00006039bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006040 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006041 KeyEntry& keyEntry, bool handled) {
6042 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006043 if (!handled) {
6044 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006045 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006046 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006047 return false;
6048 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006049
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006050 // Get the fallback key state.
6051 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006052 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006053 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006054 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006055 connection->inputState.removeFallbackKey(originalKeyCode);
6056 }
6057
6058 if (handled || !dispatchEntry->hasForegroundTarget()) {
6059 // If the application handles the original key for which we previously
6060 // generated a fallback or if the window is not a foreground window,
6061 // then cancel the associated fallback key, if any.
6062 if (fallbackKeyCode != -1) {
6063 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006064 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6065 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
6066 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6067 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
6068 keyEntry.policyFlags);
6069 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006070 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006071 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006072
6073 mLock.unlock();
6074
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006075 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006076 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006077
6078 mLock.lock();
6079
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006080 // Cancel the fallback key.
6081 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00006082 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006083 "application handled the original non-fallback key "
6084 "or is no longer a foreground target, "
6085 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08006086 options.keyCode = fallbackKeyCode;
6087 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006088 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006089 connection->inputState.removeFallbackKey(originalKeyCode);
6090 }
6091 } else {
6092 // If the application did not handle a non-fallback key, first check
6093 // that we are in a good state to perform unhandled key event processing
6094 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006095 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006096 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006097 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6098 ALOGD("Unhandled key event: Skipping unhandled key event processing "
6099 "since this is not an initial down. "
6100 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6101 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6102 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006103 return false;
6104 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006105
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006106 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006107 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6108 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
6109 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6110 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6111 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006112 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006113
6114 mLock.unlock();
6115
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006116 bool fallback =
6117 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006118 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006119
6120 mLock.lock();
6121
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08006122 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006123 connection->inputState.removeFallbackKey(originalKeyCode);
6124 return false;
6125 }
6126
6127 // Latch the fallback keycode for this key on an initial down.
6128 // The fallback keycode cannot change at any other point in the lifecycle.
6129 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006130 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006131 fallbackKeyCode = event.getKeyCode();
6132 } else {
6133 fallbackKeyCode = AKEYCODE_UNKNOWN;
6134 }
6135 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
6136 }
6137
6138 ALOG_ASSERT(fallbackKeyCode != -1);
6139
6140 // Cancel the fallback key if the policy decides not to send it anymore.
6141 // We will continue to dispatch the key to the policy but we will no
6142 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006143 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
6144 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006145 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6146 if (fallback) {
6147 ALOGD("Unhandled key event: Policy requested to send key %d"
6148 "as a fallback for %d, but on the DOWN it had requested "
6149 "to send %d instead. Fallback canceled.",
6150 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
6151 } else {
6152 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6153 "but on the DOWN it had requested to send %d. "
6154 "Fallback canceled.",
6155 originalKeyCode, fallbackKeyCode);
6156 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006157 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006158
Michael Wrightfb04fd52022-11-24 22:31:11 +00006159 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006160 "canceling fallback, policy no longer desires it");
6161 options.keyCode = fallbackKeyCode;
6162 synthesizeCancelationEventsForConnectionLocked(connection, options);
6163
6164 fallback = false;
6165 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006166 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006167 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006168 }
6169 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006170
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006171 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6172 {
6173 std::string msg;
6174 const KeyedVector<int32_t, int32_t>& fallbackKeys =
6175 connection->inputState.getFallbackKeys();
6176 for (size_t i = 0; i < fallbackKeys.size(); i++) {
6177 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
6178 }
6179 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6180 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006181 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006182 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006183
6184 if (fallback) {
6185 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006186 keyEntry.eventTime = event.getEventTime();
6187 keyEntry.deviceId = event.getDeviceId();
6188 keyEntry.source = event.getSource();
6189 keyEntry.displayId = event.getDisplayId();
6190 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
6191 keyEntry.keyCode = fallbackKeyCode;
6192 keyEntry.scanCode = event.getScanCode();
6193 keyEntry.metaState = event.getMetaState();
6194 keyEntry.repeatCount = event.getRepeatCount();
6195 keyEntry.downTime = event.getDownTime();
6196 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006197
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006198 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6199 ALOGD("Unhandled key event: Dispatching fallback key. "
6200 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
6201 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
6202 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006203 return true; // restart the event
6204 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006205 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6206 ALOGD("Unhandled key event: No fallback key.");
6207 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006208
6209 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006210 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006211 }
6212 }
6213 return false;
6214}
6215
Prabir Pradhancef936d2021-07-21 16:17:52 +00006216bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006217 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006218 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006219 return false;
6220}
6221
Michael Wrightd02c5b62014-02-10 15:10:22 -08006222void InputDispatcher::traceInboundQueueLengthLocked() {
6223 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006224 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006225 }
6226}
6227
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006228void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006229 if (ATRACE_ENABLED()) {
6230 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006231 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6232 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006233 }
6234}
6235
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006236void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006237 if (ATRACE_ENABLED()) {
6238 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006239 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6240 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006241 }
6242}
6243
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006244void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006245 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006246
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006247 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006248 dumpDispatchStateLocked(dump);
6249
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006250 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006251 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006252 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006253 }
6254}
6255
6256void InputDispatcher::monitor() {
6257 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006258 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006259 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006260 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006261}
6262
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006263/**
6264 * Wake up the dispatcher and wait until it processes all events and commands.
6265 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6266 * this method can be safely called from any thread, as long as you've ensured that
6267 * the work you are interested in completing has already been queued.
6268 */
6269bool InputDispatcher::waitForIdle() {
6270 /**
6271 * Timeout should represent the longest possible time that a device might spend processing
6272 * events and commands.
6273 */
6274 constexpr std::chrono::duration TIMEOUT = 100ms;
6275 std::unique_lock lock(mLock);
6276 mLooper->wake();
6277 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6278 return result == std::cv_status::no_timeout;
6279}
6280
Vishnu Naire798b472020-07-23 13:52:21 -07006281/**
6282 * Sets focus to the window identified by the token. This must be called
6283 * after updating any input window handles.
6284 *
6285 * Params:
6286 * request.token - input channel token used to identify the window that should gain focus.
6287 * request.focusedToken - the token that the caller expects currently to be focused. If the
6288 * specified token does not match the currently focused window, this request will be dropped.
6289 * If the specified focused token matches the currently focused window, the call will succeed.
6290 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6291 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6292 * when requesting the focus change. This determines which request gets
6293 * precedence if there is a focus change request from another source such as pointer down.
6294 */
Vishnu Nair958da932020-08-21 17:12:37 -07006295void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6296 { // acquire lock
6297 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006298 std::optional<FocusResolver::FocusChanges> changes =
6299 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6300 if (changes) {
6301 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006302 }
6303 } // release lock
6304 // Wake up poll loop since it may need to make new input dispatching choices.
6305 mLooper->wake();
6306}
6307
Vishnu Nairc519ff72021-01-21 08:23:08 -08006308void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6309 if (changes.oldFocus) {
6310 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006311 if (focusedInputChannel) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00006312 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006313 "focus left window");
6314 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006315 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006316 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006317 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006318 if (changes.newFocus) {
6319 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006320 }
6321
Prabir Pradhan99987712020-11-10 18:43:05 -08006322 // If a window has pointer capture, then it must have focus. We need to ensure that this
6323 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6324 // If the window loses focus before it loses pointer capture, then the window can be in a state
6325 // where it has pointer capture but not focus, violating the contract. Therefore we must
6326 // dispatch the pointer capture event before the focus event. Since focus events are added to
6327 // the front of the queue (above), we add the pointer capture event to the front of the queue
6328 // after the focus events are added. This ensures the pointer capture event ends up at the
6329 // front.
6330 disablePointerCaptureForcedLocked();
6331
Vishnu Nairc519ff72021-01-21 08:23:08 -08006332 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006333 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006334 }
6335}
Vishnu Nair958da932020-08-21 17:12:37 -07006336
Prabir Pradhan99987712020-11-10 18:43:05 -08006337void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006338 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006339 return;
6340 }
6341
6342 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6343
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006344 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006345 setPointerCaptureLocked(false);
6346 }
6347
6348 if (!mWindowTokenWithPointerCapture) {
6349 // No need to send capture changes because no window has capture.
6350 return;
6351 }
6352
6353 if (mPendingEvent != nullptr) {
6354 // Move the pending event to the front of the queue. This will give the chance
6355 // for the pending event to be dropped if it is a captured event.
6356 mInboundQueue.push_front(mPendingEvent);
6357 mPendingEvent = nullptr;
6358 }
6359
6360 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006361 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006362 mInboundQueue.push_front(std::move(entry));
6363}
6364
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006365void InputDispatcher::setPointerCaptureLocked(bool enable) {
6366 mCurrentPointerCaptureRequest.enable = enable;
6367 mCurrentPointerCaptureRequest.seq++;
6368 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006369 scoped_unlock unlock(mLock);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006370 mPolicy->setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006371 };
6372 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006373}
6374
Vishnu Nair599f1412021-06-21 10:39:58 -07006375void InputDispatcher::displayRemoved(int32_t displayId) {
6376 { // acquire lock
6377 std::scoped_lock _l(mLock);
6378 // Set an empty list to remove all handles from the specific display.
6379 setInputWindowsLocked(/* window handles */ {}, displayId);
6380 setFocusedApplicationLocked(displayId, nullptr);
6381 // Call focus resolver to clean up stale requests. This must be called after input windows
6382 // have been removed for the removed display.
6383 mFocusResolver.displayRemoved(displayId);
Christine Franksb768bb42021-11-29 12:11:31 -08006384 // Reset pointer capture eligibility, regardless of previous state.
6385 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
Antonio Kantek15beb512022-06-13 22:35:41 +00006386 // Remove the associated touch mode state.
6387 mTouchModePerDisplay.erase(displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006388 } // release lock
6389
6390 // Wake up poll loop since it may need to make new input dispatching choices.
6391 mLooper->wake();
6392}
6393
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006394void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
6395 const std::vector<DisplayInfo>& displayInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006396 // The listener sends the windows as a flattened array. Separate the windows by display for
6397 // more convenient parsing.
6398 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
chaviw15fab6f2021-06-07 14:15:52 -05006399 for (const auto& info : windowInfos) {
6400 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07006401 handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
chaviw15fab6f2021-06-07 14:15:52 -05006402 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006403
6404 { // acquire lock
6405 std::scoped_lock _l(mLock);
Prabir Pradhan814fe082022-07-22 20:22:18 +00006406
6407 // Ensure that we have an entry created for all existing displays so that if a displayId has
6408 // no windows, we can tell that the windows were removed from the display.
6409 for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
6410 handlesPerDisplay[displayId];
6411 }
6412
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006413 mDisplayInfos.clear();
6414 for (const auto& displayInfo : displayInfos) {
6415 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6416 }
6417
6418 for (const auto& [displayId, handles] : handlesPerDisplay) {
6419 setInputWindowsLocked(handles, displayId);
6420 }
6421 }
6422 // Wake up poll loop since it may need to make new input dispatching choices.
6423 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006424}
6425
Vishnu Nair062a8672021-09-03 16:07:44 -07006426bool InputDispatcher::shouldDropInput(
6427 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006428 if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
6429 (windowHandle->getInfo()->inputConfig.test(
6430 WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
Vishnu Nair062a8672021-09-03 16:07:44 -07006431 isWindowObscuredLocked(windowHandle))) {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006432 ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on "
6433 "display %" PRId32 ".",
Vishnu Nair062a8672021-09-03 16:07:44 -07006434 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006435 windowHandle->getInfo()->inputConfig.string().c_str(),
Vishnu Nair062a8672021-09-03 16:07:44 -07006436 windowHandle->getInfo()->displayId);
6437 return true;
6438 }
6439 return false;
6440}
6441
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006442void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
6443 const std::vector<gui::WindowInfo>& windowInfos,
6444 const std::vector<DisplayInfo>& displayInfos) {
6445 mDispatcher.onWindowInfosChanged(windowInfos, displayInfos);
6446}
6447
Arthur Hungdfd528e2021-12-08 13:23:04 +00006448void InputDispatcher::cancelCurrentTouch() {
6449 {
6450 std::scoped_lock _l(mLock);
6451 ALOGD("Canceling all ongoing pointer gestures on all displays.");
Michael Wrightfb04fd52022-11-24 22:31:11 +00006452 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Arthur Hungdfd528e2021-12-08 13:23:04 +00006453 "cancel current touch");
6454 synthesizeCancelationEventsForAllConnectionsLocked(options);
6455
6456 mTouchStatesByDisplay.clear();
6457 mLastHoverWindowHandle.clear();
6458 }
6459 // Wake up poll loop since there might be work to do.
6460 mLooper->wake();
6461}
6462
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08006463void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout) {
6464 std::scoped_lock _l(mLock);
6465 mMonitorDispatchingTimeout = timeout;
6466}
6467
Garfield Tane84e6f92019-08-29 17:28:41 -07006468} // namespace android::inputdispatcher