blob: 695dd17d389e67173e5c64b6b33a7a9d0faf8c31 [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
Prabir Pradhand2c9e8e2021-05-24 15:00:12 -070022#include <InputFlingerProperties.sysprop.h>
Michael Wright2b3c3302018-03-02 17:19:13 +000023#include <android-base/chrono_utils.h>
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080024#include <android-base/properties.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080025#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050026#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070027#include <binder/Binder.h>
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100028#include <binder/IServiceManager.h>
29#include <com/android/internal/compat/IPlatformCompatNative.h>
Dominik Laskowski75788452021-02-09 18:51:25 -080030#include <ftl/enum.h>
chaviw15fab6f2021-06-07 14:15:52 -050031#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080032#include <input/InputDevice.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070033#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000034#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070035#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010036#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070037#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080038
Michael Wright44753b12020-07-08 13:48:11 +010039#include <cerrno>
40#include <cinttypes>
41#include <climits>
42#include <cstddef>
43#include <ctime>
44#include <queue>
45#include <sstream>
46
47#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070048#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010049
Michael Wrightd02c5b62014-02-10 15:10:22 -080050#define INDENT " "
51#define INDENT2 " "
52#define INDENT3 " "
53#define INDENT4 " "
54
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::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100064using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080065using android::os::InputEventInjectionResult;
66using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100067using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080068
Garfield Tane84e6f92019-08-29 17:28:41 -070069namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080070
Prabir Pradhancef936d2021-07-21 16:17:52 +000071namespace {
72
Prabir Pradhan61a5d242021-07-26 16:41:09 +000073// Log detailed debug messages about each inbound event notification to the dispatcher.
74constexpr bool DEBUG_INBOUND_EVENT_DETAILS = false;
75
76// Log detailed debug messages about each outbound event processed by the dispatcher.
77constexpr bool DEBUG_OUTBOUND_EVENT_DETAILS = false;
78
79// Log debug messages about the dispatch cycle.
80constexpr bool DEBUG_DISPATCH_CYCLE = false;
81
82// Log debug messages about channel creation
83constexpr bool DEBUG_CHANNEL_CREATION = false;
84
85// Log debug messages about input event injection.
86constexpr bool DEBUG_INJECTION = false;
87
88// Log debug messages about input focus tracking.
89constexpr bool DEBUG_FOCUS = false;
90
91// Log debug messages about touch occlusion
92// STOPSHIP(b/169067926): Set to false
93constexpr bool DEBUG_TOUCH_OCCLUSION = true;
94
95// Log debug messages about the app switch latency optimization.
96constexpr bool DEBUG_APP_SWITCH = false;
97
98// Log debug messages about hover events.
99constexpr bool DEBUG_HOVER = false;
100
Prabir Pradhancef936d2021-07-21 16:17:52 +0000101// Temporarily releases a held mutex for the lifetime of the instance.
102// Named to match std::scoped_lock
103class scoped_unlock {
104public:
105 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
106 ~scoped_unlock() { mMutex.lock(); }
107
108private:
109 std::mutex& mMutex;
110};
111
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700112// When per-window-input-rotation is enabled, InputFlinger works in the un-rotated display
113// coordinates and SurfaceFlinger includes the display rotation in the input window transforms.
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000114bool isPerWindowInputRotationEnabled() {
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700115 static const bool PER_WINDOW_INPUT_ROTATION =
Vadim Tryshev7719c7d2021-08-27 17:28:43 +0000116 sysprop::InputFlingerProperties::per_window_input_rotation().value_or(false);
Prabir Pradhand2c9e8e2021-05-24 15:00:12 -0700117
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700118 return PER_WINDOW_INPUT_ROTATION;
119}
120
Michael Wrightd02c5b62014-02-10 15:10:22 -0800121// Default input dispatching timeout if there is no focused application or paused window
122// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -0800123const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
124 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
125 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800126
127// Amount of time to allow for all pending events to be processed when an app switch
128// key is on the way. This is used to preempt input dispatch and drop input events
129// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000130constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800131
132// Amount of time to allow for an event to be dispatched (measured since its eventTime)
133// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000134constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800135
Michael Wrightd02c5b62014-02-10 15:10:22 -0800136// 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 +0000137constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
138
139// Log a warning when an interception call takes longer than this to process.
140constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800141
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700142// Additional key latency in case a connection is still processing some motion events.
143// This will help with the case when a user touched a button that opens a new window,
144// and gives us the chance to dispatch the key to this new window.
145constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
146
Michael Wrightd02c5b62014-02-10 15:10:22 -0800147// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000148constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
149
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000150// Event log tags. See EventLogTags.logtags for reference
151constexpr int LOGTAG_INPUT_INTERACTION = 62000;
152constexpr int LOGTAG_INPUT_FOCUS = 62001;
153
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000154inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800155 return systemTime(SYSTEM_TIME_MONOTONIC);
156}
157
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000158inline const char* toString(bool value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800159 return value ? "true" : "false";
160}
161
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000162inline const std::string toString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000163 if (binder == nullptr) {
164 return "<null>";
165 }
166 return StringPrintf("%p", binder.get());
167}
168
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000169inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700170 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
171 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800172}
173
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000174bool isValidKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800175 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700176 case AKEY_EVENT_ACTION_DOWN:
177 case AKEY_EVENT_ACTION_UP:
178 return true;
179 default:
180 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800181 }
182}
183
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000184bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700185 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186 ALOGE("Key event has invalid action code 0x%x", action);
187 return false;
188 }
189 return true;
190}
191
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000192bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800193 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700194 case AMOTION_EVENT_ACTION_DOWN:
195 case AMOTION_EVENT_ACTION_UP:
196 case AMOTION_EVENT_ACTION_CANCEL:
197 case AMOTION_EVENT_ACTION_MOVE:
198 case AMOTION_EVENT_ACTION_OUTSIDE:
199 case AMOTION_EVENT_ACTION_HOVER_ENTER:
200 case AMOTION_EVENT_ACTION_HOVER_MOVE:
201 case AMOTION_EVENT_ACTION_HOVER_EXIT:
202 case AMOTION_EVENT_ACTION_SCROLL:
203 return true;
204 case AMOTION_EVENT_ACTION_POINTER_DOWN:
205 case AMOTION_EVENT_ACTION_POINTER_UP: {
206 int32_t index = getMotionEventActionPointerIndex(action);
207 return index >= 0 && index < pointerCount;
208 }
209 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
210 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
211 return actionButton != 0;
212 default:
213 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214 }
215}
216
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000217int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500218 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
219}
220
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000221bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
222 const PointerProperties* pointerProperties) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700223 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800224 ALOGE("Motion event has invalid action code 0x%x", action);
225 return false;
226 }
227 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000228 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700229 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800230 return false;
231 }
232 BitSet32 pointerIdBits;
233 for (size_t i = 0; i < pointerCount; i++) {
234 int32_t id = pointerProperties[i].id;
235 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700236 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
237 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800238 return false;
239 }
240 if (pointerIdBits.hasBit(id)) {
241 ALOGE("Motion event has duplicate pointer id %d", id);
242 return false;
243 }
244 pointerIdBits.markBit(id);
245 }
246 return true;
247}
248
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000249std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800250 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000251 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800252 }
253
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000254 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800255 bool first = true;
256 Region::const_iterator cur = region.begin();
257 Region::const_iterator const tail = region.end();
258 while (cur != tail) {
259 if (first) {
260 first = false;
261 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800262 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800263 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800264 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800265 cur++;
266 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000267 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800268}
269
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000270std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500271 constexpr size_t maxEntries = 50; // max events to print
272 constexpr size_t skipBegin = maxEntries / 2;
273 const size_t skipEnd = queue.size() - maxEntries / 2;
274 // skip from maxEntries / 2 ... size() - maxEntries/2
275 // only print from 0 .. skipBegin and then from skipEnd .. size()
276
277 std::string dump;
278 for (size_t i = 0; i < queue.size(); i++) {
279 const DispatchEntry& entry = *queue[i];
280 if (i >= skipBegin && i < skipEnd) {
281 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
282 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
283 continue;
284 }
285 dump.append(INDENT4);
286 dump += entry.eventEntry->getDescription();
287 dump += StringPrintf(", seq=%" PRIu32
288 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
289 entry.seq, entry.targetFlags, entry.resolvedAction,
290 ns2ms(currentTime - entry.eventEntry->eventTime));
291 if (entry.deliveryTime != 0) {
292 // This entry was delivered, so add information on how long we've been waiting
293 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
294 }
295 dump.append("\n");
296 }
297 return dump;
298}
299
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700300/**
301 * Find the entry in std::unordered_map by key, and return it.
302 * If the entry is not found, return a default constructed entry.
303 *
304 * Useful when the entries are vectors, since an empty vector will be returned
305 * if the entry is not found.
306 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
307 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700308template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000309V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700310 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700311 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800312}
313
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000314bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700315 if (first == second) {
316 return true;
317 }
318
319 if (first == nullptr || second == nullptr) {
320 return false;
321 }
322
323 return first->getToken() == second->getToken();
324}
325
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000326bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000327 if (first == nullptr || second == nullptr) {
328 return false;
329 }
330 return first->applicationInfo.token != nullptr &&
331 first->applicationInfo.token == second->applicationInfo.token;
332}
333
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000334bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800335 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
336}
337
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000338std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
339 std::shared_ptr<EventEntry> eventEntry,
340 int32_t inputTargetFlags) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900341 if (eventEntry->type == EventEntry::Type::MOTION) {
342 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
Prabir Pradhan664834b2021-05-20 16:00:42 -0700343 if ((motionEntry.source & AINPUT_SOURCE_CLASS_JOYSTICK) ||
344 (motionEntry.source & AINPUT_SOURCE_CLASS_POSITION)) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900345 const ui::Transform identityTransform;
Prabir Pradhan664834b2021-05-20 16:00:42 -0700346 // Use identity transform for joystick and position-based (touchpad) events because they
347 // don't depend on the window transform.
yunho.shinf4a80b82020-11-16 21:13:57 +0900348 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700349 identityTransform, 1.0f /*globalScaleFactor*/);
yunho.shinf4a80b82020-11-16 21:13:57 +0900350 }
351 }
352
chaviw1ff3d1e2020-07-01 15:53:47 -0700353 if (inputTarget.useDefaultPointerTransform()) {
354 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700355 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700356 inputTarget.displayTransform,
357 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000358 }
359
360 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
361 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
362
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700363 std::vector<PointerCoords> pointerCoords;
364 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000365
366 // Use the first pointer information to normalize all other pointers. This could be any pointer
367 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700368 // uses the transform for the normalized pointer.
369 const ui::Transform& firstPointerTransform =
370 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
371 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000372
373 // Iterate through all pointers in the event to normalize against the first.
374 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
375 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
376 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700377 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000378
379 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700380 // First, apply the current pointer's transform to update the coordinates into
381 // window space.
382 pointerCoords[pointerIndex].transform(currTransform);
383 // Next, apply the inverse transform of the normalized coordinates so the
384 // current coordinates are transformed into the normalized coordinate space.
385 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000386 }
387
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700388 std::unique_ptr<MotionEntry> combinedMotionEntry =
389 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
390 motionEntry.deviceId, motionEntry.source,
391 motionEntry.displayId, motionEntry.policyFlags,
392 motionEntry.action, motionEntry.actionButton,
393 motionEntry.flags, motionEntry.metaState,
394 motionEntry.buttonState, motionEntry.classification,
395 motionEntry.edgeFlags, motionEntry.xPrecision,
396 motionEntry.yPrecision, motionEntry.xCursorPosition,
397 motionEntry.yCursorPosition, motionEntry.downTime,
398 motionEntry.pointerCount, motionEntry.pointerProperties,
399 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000400
401 if (motionEntry.injectionState) {
402 combinedMotionEntry->injectionState = motionEntry.injectionState;
403 combinedMotionEntry->injectionState->refCount += 1;
404 }
405
406 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700407 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700408 firstPointerTransform, inputTarget.displayTransform,
409 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000410 return dispatchEntry;
411}
412
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000413status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
414 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700415 std::unique_ptr<InputChannel> uniqueServerChannel;
416 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
417
418 serverChannel = std::move(uniqueServerChannel);
419 return result;
420}
421
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500422template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000423bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500424 if (lhs == nullptr && rhs == nullptr) {
425 return true;
426 }
427 if (lhs == nullptr || rhs == nullptr) {
428 return false;
429 }
430 return *lhs == *rhs;
431}
432
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000433sp<IPlatformCompatNative> getCompatService() {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000434 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
435 if (service == nullptr) {
436 ALOGE("Failed to link to compat service");
437 return nullptr;
438 }
439 return interface_cast<IPlatformCompatNative>(service);
440}
441
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000442KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000443 KeyEvent event;
444 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
445 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
446 entry.repeatCount, entry.downTime, entry.eventTime);
447 return event;
448}
449
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000450std::optional<int32_t> findMonitorPidByToken(
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000451 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
452 const sp<IBinder>& token) {
453 for (const auto& it : monitorsByDisplay) {
454 const std::vector<Monitor>& monitors = it.second;
455 for (const Monitor& monitor : monitors) {
456 if (monitor.inputChannel->getConnectionToken() == token) {
457 return monitor.pid;
458 }
459 }
460 }
461 return std::nullopt;
462}
463
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000464bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000465 // Do not keep track of gesture monitors. They receive every event and would disproportionately
466 // affect the statistics.
467 if (connection.monitor) {
468 return false;
469 }
470 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
471 if (!connection.responsive) {
472 return false;
473 }
474 return true;
475}
476
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000477bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000478 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
479 const int32_t& inputEventId = eventEntry.id;
480 if (inputEventId != dispatchEntry.resolvedEventId) {
481 // Event was transmuted
482 return false;
483 }
484 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
485 return false;
486 }
487 // Only track latency for events that originated from hardware
488 if (eventEntry.isSynthesized()) {
489 return false;
490 }
491 const EventEntry::Type& inputEventEntryType = eventEntry.type;
492 if (inputEventEntryType == EventEntry::Type::KEY) {
493 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
494 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
495 return false;
496 }
497 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
498 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
499 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
500 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
501 return false;
502 }
503 } else {
504 // Not a key or a motion
505 return false;
506 }
507 if (!shouldReportMetricsForConnection(connection)) {
508 return false;
509 }
510 return true;
511}
512
Prabir Pradhancef936d2021-07-21 16:17:52 +0000513/**
514 * Connection is responsive if it has no events in the waitQueue that are older than the
515 * current time.
516 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000517bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000518 const nsecs_t currentTime = now();
519 for (const DispatchEntry* entry : connection.waitQueue) {
520 if (entry->timeoutTime < currentTime) {
521 return false;
522 }
523 }
524 return true;
525}
526
Prabir Pradhan81420cc2021-09-06 10:28:50 -0700527bool isFromSource(uint32_t source, uint32_t test) {
528 return (source & test) == test;
529}
530
531vec2 transformWithoutTranslation(const ui::Transform& transform, float x, float y) {
532 const vec2 transformedXy = transform.transform(x, y);
533 const vec2 transformedOrigin = transform.transform(0, 0);
534 return transformedXy - transformedOrigin;
535}
536
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000537} // namespace
538
Michael Wrightd02c5b62014-02-10 15:10:22 -0800539// --- InputDispatcher ---
540
Garfield Tan00f511d2019-06-12 16:55:40 -0700541InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
542 : mPolicy(policy),
543 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700544 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800545 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700546 mAppSwitchSawKeyDown(false),
547 mAppSwitchDueTime(LONG_LONG_MAX),
548 mNextUnblockedEvent(nullptr),
549 mDispatchEnabled(false),
550 mDispatchFrozen(false),
551 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800552 // mInTouchMode will be initialized by the WindowManager to the default device config.
553 // To avoid leaking stack in case that call never comes, and for tests,
554 // initialize it here anyways.
555 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100556 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000557 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800558 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000559 mLatencyAggregator(),
560 mLatencyTracker(&mLatencyAggregator),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000561 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800562 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800563 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800564
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700565 mWindowInfoListener = new DispatcherWindowListener(*this);
566 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
567
Yi Kong9b14ac62018-07-17 13:48:38 -0700568 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800569
570 policy->getDispatcherConfiguration(&mConfig);
571}
572
573InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000574 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800575
Prabir Pradhancef936d2021-07-21 16:17:52 +0000576 resetKeyRepeatLocked();
577 releasePendingEventLocked();
578 drainInboundQueueLocked();
579 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800580
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000581 while (!mConnectionsByToken.empty()) {
582 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000583 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
584 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800585 }
586}
587
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700588status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700589 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700590 return ALREADY_EXISTS;
591 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700592 mThread = std::make_unique<InputThread>(
593 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
594 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700595}
596
597status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700598 if (mThread && mThread->isCallingThread()) {
599 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700600 return INVALID_OPERATION;
601 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700602 mThread.reset();
603 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700604}
605
Michael Wrightd02c5b62014-02-10 15:10:22 -0800606void InputDispatcher::dispatchOnce() {
607 nsecs_t nextWakeupTime = LONG_LONG_MAX;
608 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800609 std::scoped_lock _l(mLock);
610 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800611
612 // Run a dispatch loop if there are no pending commands.
613 // The dispatch loop might enqueue commands to run afterwards.
614 if (!haveCommandsLocked()) {
615 dispatchOnceInnerLocked(&nextWakeupTime);
616 }
617
618 // Run all pending commands if there are any.
619 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000620 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800621 nextWakeupTime = LONG_LONG_MIN;
622 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800623
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700624 // If we are still waiting for ack on some events,
625 // we might have to wake up earlier to check if an app is anr'ing.
626 const nsecs_t nextAnrCheck = processAnrsLocked();
627 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
628
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800629 // We are about to enter an infinitely long sleep, because we have no commands or
630 // pending or queued events
631 if (nextWakeupTime == LONG_LONG_MAX) {
632 mDispatcherEnteredIdle.notify_all();
633 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800634 } // release lock
635
636 // Wait for callback or timeout or wake. (make sure we round up, not down)
637 nsecs_t currentTime = now();
638 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
639 mLooper->pollOnce(timeoutMillis);
640}
641
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700642/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500643 * Raise ANR if there is no focused window.
644 * Before the ANR is raised, do a final state check:
645 * 1. The currently focused application must be the same one we are waiting for.
646 * 2. Ensure we still don't have a focused window.
647 */
648void InputDispatcher::processNoFocusedWindowAnrLocked() {
649 // Check if the application that we are waiting for is still focused.
650 std::shared_ptr<InputApplicationHandle> focusedApplication =
651 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
652 if (focusedApplication == nullptr ||
653 focusedApplication->getApplicationToken() !=
654 mAwaitedFocusedApplication->getApplicationToken()) {
655 // Unexpected because we should have reset the ANR timer when focused application changed
656 ALOGE("Waited for a focused window, but focused application has already changed to %s",
657 focusedApplication->getName().c_str());
658 return; // The focused application has changed.
659 }
660
chaviw98318de2021-05-19 16:45:23 -0500661 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500662 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
663 if (focusedWindowHandle != nullptr) {
664 return; // We now have a focused window. No need for ANR.
665 }
666 onAnrLocked(mAwaitedFocusedApplication);
667}
668
669/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700670 * Check if any of the connections' wait queues have events that are too old.
671 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
672 * Return the time at which we should wake up next.
673 */
674nsecs_t InputDispatcher::processAnrsLocked() {
675 const nsecs_t currentTime = now();
676 nsecs_t nextAnrCheck = LONG_LONG_MAX;
677 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
678 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
679 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500680 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700681 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500682 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700683 return LONG_LONG_MIN;
684 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500685 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700686 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
687 }
688 }
689
690 // Check if any connection ANRs are due
691 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
692 if (currentTime < nextAnrCheck) { // most likely scenario
693 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
694 }
695
696 // If we reached here, we have an unresponsive connection.
697 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
698 if (connection == nullptr) {
699 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
700 return nextAnrCheck;
701 }
702 connection->responsive = false;
703 // Stop waking up for this unresponsive connection
704 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000705 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700706 return LONG_LONG_MIN;
707}
708
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500709std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
chaviw98318de2021-05-19 16:45:23 -0500710 sp<WindowInfoHandle> window = getWindowHandleLocked(token);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700711 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500712 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700713 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500714 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700715}
716
Michael Wrightd02c5b62014-02-10 15:10:22 -0800717void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
718 nsecs_t currentTime = now();
719
Jeff Browndc5992e2014-04-11 01:27:26 -0700720 // Reset the key repeat timer whenever normal dispatch is suspended while the
721 // device is in a non-interactive state. This is to ensure that we abort a key
722 // repeat if the device is just coming out of sleep.
723 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800724 resetKeyRepeatLocked();
725 }
726
727 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
728 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100729 if (DEBUG_FOCUS) {
730 ALOGD("Dispatch frozen. Waiting some more.");
731 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800732 return;
733 }
734
735 // Optimize latency of app switches.
736 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
737 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
738 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
739 if (mAppSwitchDueTime < *nextWakeupTime) {
740 *nextWakeupTime = mAppSwitchDueTime;
741 }
742
743 // Ready to start a new event.
744 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700745 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700746 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800747 if (isAppSwitchDue) {
748 // The inbound queue is empty so the app switch key we were waiting
749 // for will never arrive. Stop waiting for it.
750 resetPendingAppSwitchLocked(false);
751 isAppSwitchDue = false;
752 }
753
754 // Synthesize a key repeat if appropriate.
755 if (mKeyRepeatState.lastKeyEntry) {
756 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
757 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
758 } else {
759 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
760 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
761 }
762 }
763 }
764
765 // Nothing to do if there is no pending event.
766 if (!mPendingEvent) {
767 return;
768 }
769 } else {
770 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700771 mPendingEvent = mInboundQueue.front();
772 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800773 traceInboundQueueLengthLocked();
774 }
775
776 // Poke user activity for this event.
777 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700778 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800779 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800780 }
781
782 // Now we have an event to dispatch.
783 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700784 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800785 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700786 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800787 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700788 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800789 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700790 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800791 }
792
793 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700794 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800795 }
796
797 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700798 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700799 const ConfigurationChangedEntry& typedEntry =
800 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700801 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700802 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700803 break;
804 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800805
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700806 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700807 const DeviceResetEntry& typedEntry =
808 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700809 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700810 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700811 break;
812 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800813
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100814 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700815 std::shared_ptr<FocusEntry> typedEntry =
816 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100817 dispatchFocusLocked(currentTime, typedEntry);
818 done = true;
819 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
820 break;
821 }
822
Antonio Kantek7242d8b2021-08-05 16:07:20 -0700823 case EventEntry::Type::TOUCH_MODE_CHANGED: {
824 const auto typedEntry = std::static_pointer_cast<TouchModeEntry>(mPendingEvent);
825 dispatchTouchModeChangeLocked(currentTime, typedEntry);
826 done = true;
827 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
828 break;
829 }
830
Prabir Pradhan99987712020-11-10 18:43:05 -0800831 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
832 const auto typedEntry =
833 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
834 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
835 done = true;
836 break;
837 }
838
arthurhungb89ccb02020-12-30 16:19:01 +0800839 case EventEntry::Type::DRAG: {
840 std::shared_ptr<DragEntry> typedEntry =
841 std::static_pointer_cast<DragEntry>(mPendingEvent);
842 dispatchDragLocked(currentTime, typedEntry);
843 done = true;
844 break;
845 }
846
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700847 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700848 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700849 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700850 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700851 resetPendingAppSwitchLocked(true);
852 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700853 } else if (dropReason == DropReason::NOT_DROPPED) {
854 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700855 }
856 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700857 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700858 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700859 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700860 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
861 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700862 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700863 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700864 break;
865 }
866
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700867 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700868 std::shared_ptr<MotionEntry> motionEntry =
869 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700870 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
871 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800872 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700873 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700874 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700875 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700876 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
877 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700878 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700879 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700880 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800881 }
Chris Yef59a2f42020-10-16 12:55:26 -0700882
883 case EventEntry::Type::SENSOR: {
884 std::shared_ptr<SensorEntry> sensorEntry =
885 std::static_pointer_cast<SensorEntry>(mPendingEvent);
886 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
887 dropReason = DropReason::APP_SWITCH;
888 }
889 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
890 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
891 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
892 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
893 dropReason = DropReason::STALE;
894 }
895 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
896 done = true;
897 break;
898 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800899 }
900
901 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700902 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700903 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800904 }
Michael Wright3a981722015-06-10 15:26:13 +0100905 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800906
907 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700908 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800909 }
910}
911
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700912/**
913 * Return true if the events preceding this incoming motion event should be dropped
914 * Return false otherwise (the default behaviour)
915 */
916bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700917 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700918 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700919
920 // Optimize case where the current application is unresponsive and the user
921 // decides to touch a window in a different application.
922 // If the application takes too long to catch up then we drop all events preceding
923 // the touch into the other window.
924 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700925 int32_t displayId = motionEntry.displayId;
926 int32_t x = static_cast<int32_t>(
927 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
928 int32_t y = static_cast<int32_t>(
929 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
chaviw98318de2021-05-19 16:45:23 -0500930 sp<WindowInfoHandle> touchedWindowHandle =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700931 findTouchedWindowAtLocked(displayId, x, y, nullptr);
932 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700933 touchedWindowHandle->getApplicationToken() !=
934 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700935 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700936 ALOGI("Pruning input queue because user touched a different application while waiting "
937 "for %s",
938 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700939 return true;
940 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700941
942 // Alternatively, maybe there's a gesture monitor that could handle this event
Prabir Pradhan0a99c922021-09-03 08:27:53 -0700943 for (const auto& monitor : getValueByKey(mGestureMonitorsByDisplay, displayId)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700944 sp<Connection> connection =
Prabir Pradhan0a99c922021-09-03 08:27:53 -0700945 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000946 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700947 // This monitor could take more input. Drop all events preceding this
948 // event, so that gesture monitor could get a chance to receive the stream
949 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
950 "responsive gesture monitor that may handle the event",
951 mAwaitedFocusedApplication->getName().c_str());
952 return true;
953 }
954 }
955 }
956
957 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
958 // yet been processed by some connections, the dispatcher will wait for these motion
959 // events to be processed before dispatching the key event. This is because these motion events
960 // may cause a new window to be launched, which the user might expect to receive focus.
961 // To prevent waiting forever for such events, just send the key to the currently focused window
962 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
963 ALOGD("Received a new pointer down event, stop waiting for events to process and "
964 "just send the pending key event to the focused window.");
965 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700966 }
967 return false;
968}
969
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700970bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700971 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700972 mInboundQueue.push_back(std::move(newEntry));
973 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800974 traceInboundQueueLengthLocked();
975
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700976 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700977 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700978 // Optimize app switch latency.
979 // If the application takes too long to catch up then we drop all events preceding
980 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700981 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700982 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700983 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700984 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700985 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700986 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000987 if (DEBUG_APP_SWITCH) {
988 ALOGD("App switch is pending!");
989 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700990 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700991 mAppSwitchSawKeyDown = false;
992 needWake = true;
993 }
994 }
995 }
996 break;
997 }
998
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700999 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001000 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
1001 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001002 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001003 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001004 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001005 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001006 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001007 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1008 break;
1009 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001010 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001011 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001012 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001013 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001014 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1015 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001016 // nothing to do
1017 break;
1018 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001019 }
1020
1021 return needWake;
1022}
1023
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001024void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001025 // Do not store sensor event in recent queue to avoid flooding the queue.
1026 if (entry->type != EventEntry::Type::SENSOR) {
1027 mRecentQueue.push_back(entry);
1028 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001029 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001030 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001031 }
1032}
1033
chaviw98318de2021-05-19 16:45:23 -05001034sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1035 int32_t y, TouchState* touchState,
1036 bool addOutsideTargets,
1037 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001038 if (addOutsideTargets && touchState == nullptr) {
1039 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001040 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001041 // Traverse windows from front to back to find touched window.
chaviw98318de2021-05-19 16:45:23 -05001042 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
1043 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001044 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001045 continue;
1046 }
chaviw98318de2021-05-19 16:45:23 -05001047 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001048 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +01001049 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001050
1051 if (windowInfo->visible) {
chaviw98318de2021-05-19 16:45:23 -05001052 if (!flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
1053 bool isTouchModal = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
1054 !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001055 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
1056 // Found window.
1057 return windowHandle;
1058 }
1059 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001060
chaviw98318de2021-05-19 16:45:23 -05001061 if (addOutsideTargets && flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001062 touchState->addOrUpdateWindow(windowHandle,
1063 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1064 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001065 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001066 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001067 }
1068 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001069 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001070}
1071
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001072void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001073 const char* reason;
1074 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001075 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001076 if (DEBUG_INBOUND_EVENT_DETAILS) {
1077 ALOGD("Dropped event because policy consumed it.");
1078 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001079 reason = "inbound event was dropped because the policy consumed it";
1080 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001081 case DropReason::DISABLED:
1082 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001083 ALOGI("Dropped event because input dispatch is disabled.");
1084 }
1085 reason = "inbound event was dropped because input dispatch is disabled";
1086 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001087 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001088 ALOGI("Dropped event because of pending overdue app switch.");
1089 reason = "inbound event was dropped because of pending overdue app switch";
1090 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001091 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001092 ALOGI("Dropped event because the current application is not responding and the user "
1093 "has started interacting with a different application.");
1094 reason = "inbound event was dropped because the current application is not responding "
1095 "and the user has started interacting with a different application";
1096 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001097 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001098 ALOGI("Dropped event because it is stale.");
1099 reason = "inbound event was dropped because it is stale";
1100 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001101 case DropReason::NO_POINTER_CAPTURE:
1102 ALOGI("Dropped event because there is no window with Pointer Capture.");
1103 reason = "inbound event was dropped because there is no window with Pointer Capture";
1104 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001105 case DropReason::NOT_DROPPED: {
1106 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001107 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001108 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001109 }
1110
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001111 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001112 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001113 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1114 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001115 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001116 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001117 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001118 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1119 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001120 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1121 synthesizeCancelationEventsForAllConnectionsLocked(options);
1122 } else {
1123 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1124 synthesizeCancelationEventsForAllConnectionsLocked(options);
1125 }
1126 break;
1127 }
Chris Yef59a2f42020-10-16 12:55:26 -07001128 case EventEntry::Type::SENSOR: {
1129 break;
1130 }
arthurhungb89ccb02020-12-30 16:19:01 +08001131 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1132 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001133 break;
1134 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001135 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001136 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001137 case EventEntry::Type::CONFIGURATION_CHANGED:
1138 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001139 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001140 break;
1141 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001142 }
1143}
1144
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001145static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001146 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1147 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001148}
1149
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001150bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1151 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1152 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1153 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001154}
1155
1156bool InputDispatcher::isAppSwitchPendingLocked() {
1157 return mAppSwitchDueTime != LONG_LONG_MAX;
1158}
1159
1160void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1161 mAppSwitchDueTime = LONG_LONG_MAX;
1162
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001163 if (DEBUG_APP_SWITCH) {
1164 if (handled) {
1165 ALOGD("App switch has arrived.");
1166 } else {
1167 ALOGD("App switch was abandoned.");
1168 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001169 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001170}
1171
Michael Wrightd02c5b62014-02-10 15:10:22 -08001172bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001173 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001174}
1175
Prabir Pradhancef936d2021-07-21 16:17:52 +00001176bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001177 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001178 return false;
1179 }
1180
1181 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001182 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001183 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001184 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1185 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001186 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001187 return true;
1188}
1189
Prabir Pradhancef936d2021-07-21 16:17:52 +00001190void InputDispatcher::postCommandLocked(Command&& command) {
1191 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001192}
1193
1194void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001195 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001196 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001197 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001198 releaseInboundEventLocked(entry);
1199 }
1200 traceInboundQueueLengthLocked();
1201}
1202
1203void InputDispatcher::releasePendingEventLocked() {
1204 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001205 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001206 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001207 }
1208}
1209
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001210void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001211 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001212 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001213 if (DEBUG_DISPATCH_CYCLE) {
1214 ALOGD("Injected inbound event was dropped.");
1215 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001216 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001217 }
1218 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001219 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001220 }
1221 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001222}
1223
1224void InputDispatcher::resetKeyRepeatLocked() {
1225 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001226 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001227 }
1228}
1229
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001230std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1231 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001232
Michael Wright2e732952014-09-24 13:26:59 -07001233 uint32_t policyFlags = entry->policyFlags &
1234 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001235
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001236 std::shared_ptr<KeyEntry> newEntry =
1237 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1238 entry->source, entry->displayId, policyFlags, entry->action,
1239 entry->flags, entry->keyCode, entry->scanCode,
1240 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001241
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001242 newEntry->syntheticRepeat = true;
1243 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001244 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001245 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001246}
1247
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001248bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001249 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001250 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1251 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1252 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001253
1254 // Reset key repeating in case a keyboard device was added or removed or something.
1255 resetKeyRepeatLocked();
1256
1257 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001258 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1259 scoped_unlock unlock(mLock);
1260 mPolicy->notifyConfigurationChanged(eventTime);
1261 };
1262 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001263 return true;
1264}
1265
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001266bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1267 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001268 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1269 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1270 entry.deviceId);
1271 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001272
liushenxiang42232912021-05-21 20:24:09 +08001273 // Reset key repeating in case a keyboard device was disabled or enabled.
1274 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1275 resetKeyRepeatLocked();
1276 }
1277
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001278 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001279 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001280 synthesizeCancelationEventsForAllConnectionsLocked(options);
1281 return true;
1282}
1283
Vishnu Nairad321cd2020-08-20 16:40:21 -07001284void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001285 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001286 if (mPendingEvent != nullptr) {
1287 // Move the pending event to the front of the queue. This will give the chance
1288 // for the pending event to get dispatched to the newly focused window
1289 mInboundQueue.push_front(mPendingEvent);
1290 mPendingEvent = nullptr;
1291 }
1292
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001293 std::unique_ptr<FocusEntry> focusEntry =
1294 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1295 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001296
1297 // This event should go to the front of the queue, but behind all other focus events
1298 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001299 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001300 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001301 [](const std::shared_ptr<EventEntry>& event) {
1302 return event->type == EventEntry::Type::FOCUS;
1303 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001304
1305 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001306 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001307}
1308
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001309void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001310 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001311 if (channel == nullptr) {
1312 return; // Window has gone away
1313 }
1314 InputTarget target;
1315 target.inputChannel = channel;
1316 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1317 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001318 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1319 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001320 std::string reason = std::string("reason=").append(entry->reason);
1321 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001322 dispatchEventLocked(currentTime, entry, {target});
1323}
1324
Prabir Pradhan99987712020-11-10 18:43:05 -08001325void InputDispatcher::dispatchPointerCaptureChangedLocked(
1326 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1327 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001328 dropReason = DropReason::NOT_DROPPED;
1329
Prabir Pradhan99987712020-11-10 18:43:05 -08001330 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001331 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001332
1333 if (entry->pointerCaptureRequest.enable) {
1334 // Enable Pointer Capture.
1335 if (haveWindowWithPointerCapture &&
1336 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1337 LOG_ALWAYS_FATAL("This request to enable Pointer Capture has already been dispatched "
1338 "to the window.");
1339 }
1340 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001341 // This can happen if a window requests capture and immediately releases capture.
1342 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001343 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001344 return;
1345 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001346 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1347 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1348 return;
1349 }
1350
Vishnu Nairc519ff72021-01-21 08:23:08 -08001351 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001352 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1353 mWindowTokenWithPointerCapture = token;
1354 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001355 // Disable Pointer Capture.
1356 // We do not check if the sequence number matches for requests to disable Pointer Capture
1357 // for two reasons:
1358 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1359 // to disable capture with the same sequence number: one generated by
1360 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1361 // Capture being disabled in InputReader.
1362 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1363 // actual Pointer Capture state that affects events being generated by input devices is
1364 // in InputReader.
1365 if (!haveWindowWithPointerCapture) {
1366 // Pointer capture was already forcefully disabled because of focus change.
1367 dropReason = DropReason::NOT_DROPPED;
1368 return;
1369 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001370 token = mWindowTokenWithPointerCapture;
1371 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001372 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001373 setPointerCaptureLocked(false);
1374 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001375 }
1376
1377 auto channel = getInputChannelLocked(token);
1378 if (channel == nullptr) {
1379 // Window has gone away, clean up Pointer Capture state.
1380 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001381 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001382 setPointerCaptureLocked(false);
1383 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001384 return;
1385 }
1386 InputTarget target;
1387 target.inputChannel = channel;
1388 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1389 entry->dispatchInProgress = true;
1390 dispatchEventLocked(currentTime, entry, {target});
1391
1392 dropReason = DropReason::NOT_DROPPED;
1393}
1394
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001395void InputDispatcher::dispatchTouchModeChangeLocked(nsecs_t currentTime,
1396 const std::shared_ptr<TouchModeEntry>& entry) {
1397 const std::vector<sp<WindowInfoHandle>>& windowHandles =
1398 getWindowHandlesLocked(mFocusedDisplayId);
1399 if (windowHandles.empty()) {
1400 return;
1401 }
1402 const std::vector<InputTarget> inputTargets =
1403 getInputTargetsFromWindowHandlesLocked(windowHandles);
1404 if (inputTargets.empty()) {
1405 return;
1406 }
1407 entry->dispatchInProgress = true;
1408 dispatchEventLocked(currentTime, entry, inputTargets);
1409}
1410
1411std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1412 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1413 std::vector<InputTarget> inputTargets;
1414 for (const sp<WindowInfoHandle>& handle : windowHandles) {
1415 // TODO(b/193718270): Due to performance concerns, consider notifying visible windows only.
1416 const sp<IBinder>& token = handle->getToken();
1417 if (token == nullptr) {
1418 continue;
1419 }
1420 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1421 if (channel == nullptr) {
1422 continue; // Window has gone away
1423 }
1424 InputTarget target;
1425 target.inputChannel = channel;
1426 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1427 inputTargets.push_back(target);
1428 }
1429 return inputTargets;
1430}
1431
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001432bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001433 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001434 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001435 if (!entry->dispatchInProgress) {
1436 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1437 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1438 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1439 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001440 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001441 // We have seen two identical key downs in a row which indicates that the device
1442 // driver is automatically generating key repeats itself. We take note of the
1443 // repeat here, but we disable our own next key repeat timer since it is clear that
1444 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001445 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1446 // Make sure we don't get key down from a different device. If a different
1447 // device Id has same key pressed down, the new device Id will replace the
1448 // current one to hold the key repeat with repeat count reset.
1449 // In the future when got a KEY_UP on the device id, drop it and do not
1450 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001451 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1452 resetKeyRepeatLocked();
1453 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1454 } else {
1455 // Not a repeat. Save key down state in case we do see a repeat later.
1456 resetKeyRepeatLocked();
1457 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1458 }
1459 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001460 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1461 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001462 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001463 if (DEBUG_INBOUND_EVENT_DETAILS) {
1464 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1465 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001466 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001467 resetKeyRepeatLocked();
1468 }
1469
1470 if (entry->repeatCount == 1) {
1471 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1472 } else {
1473 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1474 }
1475
1476 entry->dispatchInProgress = true;
1477
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001478 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001479 }
1480
1481 // Handle case where the policy asked us to try again later last time.
1482 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1483 if (currentTime < entry->interceptKeyWakeupTime) {
1484 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1485 *nextWakeupTime = entry->interceptKeyWakeupTime;
1486 }
1487 return false; // wait until next wakeup
1488 }
1489 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1490 entry->interceptKeyWakeupTime = 0;
1491 }
1492
1493 // Give the policy a chance to intercept the key.
1494 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1495 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001496 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001497 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001498
1499 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1500 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1501 };
1502 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001503 return false; // wait for the command to run
1504 } else {
1505 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1506 }
1507 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001508 if (*dropReason == DropReason::NOT_DROPPED) {
1509 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001510 }
1511 }
1512
1513 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001514 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001515 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001516 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1517 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001518 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001519 return true;
1520 }
1521
1522 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001523 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001524 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001525 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001526 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001527 return false;
1528 }
1529
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001530 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001531 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001532 return true;
1533 }
1534
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001535 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001536 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001537
1538 // Dispatch the key.
1539 dispatchEventLocked(currentTime, entry, inputTargets);
1540 return true;
1541}
1542
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001543void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001544 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1545 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1546 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1547 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1548 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1549 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1550 entry.metaState, entry.repeatCount, entry.downTime);
1551 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001552}
1553
Prabir Pradhancef936d2021-07-21 16:17:52 +00001554void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1555 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001556 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001557 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1558 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1559 "source=0x%x, sensorType=%s",
1560 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001561 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001562 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001563 auto command = [this, entry]() REQUIRES(mLock) {
1564 scoped_unlock unlock(mLock);
1565
1566 if (entry->accuracyChanged) {
1567 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1568 }
1569 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1570 entry->hwTimestamp, entry->values);
1571 };
1572 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001573}
1574
1575bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001576 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1577 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001578 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001579 }
Chris Yef59a2f42020-10-16 12:55:26 -07001580 { // acquire lock
1581 std::scoped_lock _l(mLock);
1582
1583 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1584 std::shared_ptr<EventEntry> entry = *it;
1585 if (entry->type == EventEntry::Type::SENSOR) {
1586 it = mInboundQueue.erase(it);
1587 releaseInboundEventLocked(entry);
1588 }
1589 }
1590 }
1591 return true;
1592}
1593
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001594bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001595 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001596 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001597 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001598 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001599 entry->dispatchInProgress = true;
1600
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001601 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001602 }
1603
1604 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001605 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001606 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001607 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1608 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001609 return true;
1610 }
1611
1612 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1613
1614 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001615 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001616
1617 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001618 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001619 if (isPointerEvent) {
1620 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001621 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001622 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001623 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001624 } else {
1625 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001626 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001627 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001628 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001629 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001630 return false;
1631 }
1632
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001633 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001634 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001635 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1636 return true;
1637 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001638 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001639 CancelationOptions::Mode mode(isPointerEvent
1640 ? CancelationOptions::CANCEL_POINTER_EVENTS
1641 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1642 CancelationOptions options(mode, "input event injection failed");
1643 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001644 return true;
1645 }
1646
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001647 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001648 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001649
1650 // Dispatch the motion.
1651 if (conflictingPointerActions) {
1652 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001653 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001654 synthesizeCancelationEventsForAllConnectionsLocked(options);
1655 }
1656 dispatchEventLocked(currentTime, entry, inputTargets);
1657 return true;
1658}
1659
chaviw98318de2021-05-19 16:45:23 -05001660void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001661 bool isExiting, const MotionEntry& motionEntry) {
1662 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1663 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1664 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1665 PointerCoords pointerCoords;
1666 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1667 pointerCoords.transform(windowHandle->getInfo()->transform);
1668
1669 std::unique_ptr<DragEntry> dragEntry =
1670 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1671 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1672 pointerCoords.getY());
1673
1674 enqueueInboundEventLocked(std::move(dragEntry));
1675}
1676
1677void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1678 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1679 if (channel == nullptr) {
1680 return; // Window has gone away
1681 }
1682 InputTarget target;
1683 target.inputChannel = channel;
1684 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1685 entry->dispatchInProgress = true;
1686 dispatchEventLocked(currentTime, entry, {target});
1687}
1688
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001689void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001690 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1691 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1692 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001693 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001694 "metaState=0x%x, buttonState=0x%x,"
1695 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1696 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001697 entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
1698 entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.edgeFlags,
1699 entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001700
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001701 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1702 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1703 "x=%f, y=%f, pressure=%f, size=%f, "
1704 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1705 "orientation=%f",
1706 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1707 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1708 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1709 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1710 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1711 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1712 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1713 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1714 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1715 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1716 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001717 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001718}
1719
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001720void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1721 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001722 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001723 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001724 if (DEBUG_DISPATCH_CYCLE) {
1725 ALOGD("dispatchEventToCurrentInputTargets");
1726 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001727
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001728 updateInteractionTokensLocked(*eventEntry, inputTargets);
1729
Michael Wrightd02c5b62014-02-10 15:10:22 -08001730 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1731
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001732 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001733
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001734 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001735 sp<Connection> connection =
1736 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001737 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001738 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001739 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001740 if (DEBUG_FOCUS) {
1741 ALOGD("Dropping event delivery to target with channel '%s' because it "
1742 "is no longer registered with the input dispatcher.",
1743 inputTarget.inputChannel->getName().c_str());
1744 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001745 }
1746 }
1747}
1748
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001749void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1750 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1751 // If the policy decides to close the app, we will get a channel removal event via
1752 // unregisterInputChannel, and will clean up the connection that way. We are already not
1753 // sending new pointers to the connection when it blocked, but focused events will continue to
1754 // pile up.
1755 ALOGW("Canceling events for %s because it is unresponsive",
1756 connection->inputChannel->getName().c_str());
1757 if (connection->status == Connection::STATUS_NORMAL) {
1758 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1759 "application not responding");
1760 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001761 }
1762}
1763
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001764void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001765 if (DEBUG_FOCUS) {
1766 ALOGD("Resetting ANR timeouts.");
1767 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001768
1769 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001770 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001771 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001772}
1773
Tiger Huang721e26f2018-07-24 22:26:19 +08001774/**
1775 * Get the display id that the given event should go to. If this event specifies a valid display id,
1776 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1777 * Focused display is the display that the user most recently interacted with.
1778 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001779int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001780 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001781 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001782 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001783 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1784 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001785 break;
1786 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001787 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001788 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1789 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001790 break;
1791 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001792 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001793 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001794 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001795 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001796 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001797 case EventEntry::Type::SENSOR:
1798 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001799 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001800 return ADISPLAY_ID_NONE;
1801 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001802 }
1803 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1804}
1805
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001806bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1807 const char* focusedWindowName) {
1808 if (mAnrTracker.empty()) {
1809 // already processed all events that we waited for
1810 mKeyIsWaitingForEventsTimeout = std::nullopt;
1811 return false;
1812 }
1813
1814 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1815 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001816 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001817 mKeyIsWaitingForEventsTimeout = currentTime +
1818 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1819 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001820 return true;
1821 }
1822
1823 // We still have pending events, and already started the timer
1824 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1825 return true; // Still waiting
1826 }
1827
1828 // Waited too long, and some connection still hasn't processed all motions
1829 // Just send the key to the focused window
1830 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1831 focusedWindowName);
1832 mKeyIsWaitingForEventsTimeout = std::nullopt;
1833 return false;
1834}
1835
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001836InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1837 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1838 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001839 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001840
Tiger Huang721e26f2018-07-24 22:26:19 +08001841 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001842 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001843 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001844 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1845
Michael Wrightd02c5b62014-02-10 15:10:22 -08001846 // If there is no currently focused window and no focused application
1847 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001848 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1849 ALOGI("Dropping %s event because there is no focused window or focused application in "
1850 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08001851 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001852 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001853 }
1854
Vishnu Nair062a8672021-09-03 16:07:44 -07001855 // Drop key events if requested by input feature
1856 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
1857 return InputEventInjectionResult::FAILED;
1858 }
1859
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001860 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1861 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1862 // start interacting with another application via touch (app switch). This code can be removed
1863 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1864 // an app is expected to have a focused window.
1865 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1866 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1867 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001868 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1869 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1870 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001871 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001872 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001873 ALOGW("Waiting because no window has focus but %s may eventually add a "
1874 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001875 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001876 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001877 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001878 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1879 // Already raised ANR. Drop the event
1880 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08001881 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001882 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001883 } else {
1884 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001885 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001886 }
1887 }
1888
1889 // we have a valid, non-null focused window
1890 resetNoFocusedWindowTimeoutLocked();
1891
Michael Wrightd02c5b62014-02-10 15:10:22 -08001892 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001893 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001894 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001895 }
1896
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001897 if (focusedWindowHandle->getInfo()->paused) {
1898 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001899 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001900 }
1901
1902 // If the event is a key event, then we must wait for all previous events to
1903 // complete before delivering it because previous events may have the
1904 // side-effect of transferring focus to a different window and we want to
1905 // ensure that the following keys are sent to the new window.
1906 //
1907 // Suppose the user touches a button in a window then immediately presses "A".
1908 // If the button causes a pop-up window to appear then we want to ensure that
1909 // the "A" key is delivered to the new pop-up window. This is because users
1910 // often anticipate pending UI changes when typing on a keyboard.
1911 // To obtain this behavior, we must serialize key events with respect to all
1912 // prior input events.
1913 if (entry.type == EventEntry::Type::KEY) {
1914 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1915 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001916 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001917 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001918 }
1919
1920 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001921 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001922 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1923 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001924
1925 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001926 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001927}
1928
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001929/**
1930 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1931 * that are currently unresponsive.
1932 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001933std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
1934 const std::vector<Monitor>& monitors) const {
1935 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001936 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001937 [this](const Monitor& monitor) REQUIRES(mLock) {
1938 sp<Connection> connection =
1939 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001940 if (connection == nullptr) {
1941 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001942 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001943 return false;
1944 }
1945 if (!connection->responsive) {
1946 ALOGW("Unresponsive monitor %s will not get the new gesture",
1947 connection->inputChannel->getName().c_str());
1948 return false;
1949 }
1950 return true;
1951 });
1952 return responsiveMonitors;
1953}
1954
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001955InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1956 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1957 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001958 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001959 enum InjectionPermission {
1960 INJECTION_PERMISSION_UNKNOWN,
1961 INJECTION_PERMISSION_GRANTED,
1962 INJECTION_PERMISSION_DENIED
1963 };
1964
Michael Wrightd02c5b62014-02-10 15:10:22 -08001965 // For security reasons, we defer updating the touch state until we are sure that
1966 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001967 int32_t displayId = entry.displayId;
1968 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001969 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1970
1971 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001972 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001973 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05001974 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1975 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001976
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001977 // Copy current touch state into tempTouchState.
1978 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1979 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001980 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001981 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001982 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1983 mTouchStatesByDisplay.find(displayId);
1984 if (oldStateIt != mTouchStatesByDisplay.end()) {
1985 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001986 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001987 }
1988
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001989 bool isSplit = tempTouchState.split;
1990 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1991 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1992 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001993 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1994 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1995 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1996 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1997 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001998 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001999 bool wrongDevice = false;
2000 if (newGesture) {
2001 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002002 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002003 ALOGI("Dropping event because a pointer for a different device is already down "
2004 "in display %" PRId32,
2005 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002006 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002007 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002008 switchedDevice = false;
2009 wrongDevice = true;
2010 goto Failed;
2011 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002012 tempTouchState.reset();
2013 tempTouchState.down = down;
2014 tempTouchState.deviceId = entry.deviceId;
2015 tempTouchState.source = entry.source;
2016 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002017 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002018 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002019 ALOGI("Dropping move event because a pointer for a different device is already active "
2020 "in display %" PRId32,
2021 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002022 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002023 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002024 switchedDevice = false;
2025 wrongDevice = true;
2026 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002027 }
2028
2029 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2030 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2031
Garfield Tan00f511d2019-06-12 16:55:40 -07002032 int32_t x;
2033 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002034 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07002035 // Always dispatch mouse events to cursor position.
2036 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002037 x = int32_t(entry.xCursorPosition);
2038 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07002039 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002040 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
2041 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07002042 }
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002043 const bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002044 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
2045 isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00002046
Michael Wrightd02c5b62014-02-10 15:10:22 -08002047 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002048 if (newTouchedWindowHandle != nullptr &&
2049 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07002050 // New window supports splitting, but we should never split mouse events.
2051 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002052 } else if (isSplit) {
2053 // New window does not support splitting but we have already split events.
2054 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002055 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002056 }
2057
2058 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002059 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002060 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002061 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002062 }
2063
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002064 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
2065 ALOGI("Not sending touch event to %s because it is paused",
2066 newTouchedWindowHandle->getName().c_str());
2067 newTouchedWindowHandle = nullptr;
2068 }
2069
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002070 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002071 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002072 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
2073 if (!isResponsive) {
2074 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002075 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
2076 newTouchedWindowHandle = nullptr;
2077 }
2078 }
2079
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002080 // Drop events that can't be trusted due to occlusion
2081 if (newTouchedWindowHandle != nullptr &&
2082 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2083 TouchOcclusionInfo occlusionInfo =
2084 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002085 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002086 if (DEBUG_TOUCH_OCCLUSION) {
2087 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2088 for (const auto& log : occlusionInfo.debugInfo) {
2089 ALOGD("%s", log.c_str());
2090 }
2091 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00002092 sendUntrustedTouchCommandLocked(occlusionInfo.obscuringPackage);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002093 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2094 ALOGW("Dropping untrusted touch event due to %s/%d",
2095 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2096 newTouchedWindowHandle = nullptr;
2097 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002098 }
2099 }
2100
Vishnu Nair062a8672021-09-03 16:07:44 -07002101 // Drop touch events if requested by input feature
2102 if (newTouchedWindowHandle != nullptr && shouldDropInput(entry, newTouchedWindowHandle)) {
2103 newTouchedWindowHandle = nullptr;
2104 }
2105
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002106 const std::vector<Monitor> newGestureMonitors = isDown
2107 ? selectResponsiveMonitorsLocked(
2108 getValueByKey(mGestureMonitorsByDisplay, displayId))
2109 : std::vector<Monitor>{};
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002110
Michael Wright3dd60e22019-03-27 22:06:44 +00002111 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
2112 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002113 "(%d, %d) in display %" PRId32 ".",
2114 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002115 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00002116 goto Failed;
2117 }
2118
2119 if (newTouchedWindowHandle != nullptr) {
2120 // Set target flags.
2121 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
2122 if (isSplit) {
2123 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002124 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002125 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2126 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2127 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2128 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2129 }
2130
2131 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07002132 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2133 newHoverWindowHandle = nullptr;
2134 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002135 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002136 }
2137
2138 // Update the temporary touch state.
2139 BitSet32 pointerIds;
2140 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002141 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002142 pointerIds.markBit(pointerId);
2143 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002144 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002145 }
2146
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002147 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002148 } else {
2149 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2150
2151 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002152 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002153 if (DEBUG_FOCUS) {
2154 ALOGD("Dropping event because the pointer is not down or we previously "
2155 "dropped the pointer down event in display %" PRId32,
2156 displayId);
2157 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002158 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002159 goto Failed;
2160 }
2161
arthurhung6d4bed92021-03-17 11:59:33 +08002162 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002163
Michael Wrightd02c5b62014-02-10 15:10:22 -08002164 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002165 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002166 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002167 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2168 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002169
chaviw98318de2021-05-19 16:45:23 -05002170 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002171 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002172 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Vishnu Nair062a8672021-09-03 16:07:44 -07002173
2174 // Drop touch events if requested by input feature
2175 if (newTouchedWindowHandle != nullptr &&
2176 shouldDropInput(entry, newTouchedWindowHandle)) {
2177 newTouchedWindowHandle = nullptr;
2178 }
2179
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002180 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2181 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002182 if (DEBUG_FOCUS) {
2183 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2184 oldTouchedWindowHandle->getName().c_str(),
2185 newTouchedWindowHandle->getName().c_str(), displayId);
2186 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002187 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002188 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2189 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2190 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002191
2192 // Make a slippery entrance into the new window.
2193 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2194 isSplit = true;
2195 }
2196
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002197 int32_t targetFlags =
2198 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002199 if (isSplit) {
2200 targetFlags |= InputTarget::FLAG_SPLIT;
2201 }
2202 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2203 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002204 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2205 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002206 }
2207
2208 BitSet32 pointerIds;
2209 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002210 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002211 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002212 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002213 }
2214 }
2215 }
2216
2217 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002218 // Let the previous window know that the hover sequence is over, unless we already did it
2219 // when dispatching it as is to newTouchedWindowHandle.
2220 if (mLastHoverWindowHandle != nullptr &&
2221 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2222 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002223 if (DEBUG_HOVER) {
2224 ALOGD("Sending hover exit event to window %s.",
2225 mLastHoverWindowHandle->getName().c_str());
2226 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002227 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2228 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002229 }
2230
Garfield Tandf26e862020-07-01 20:18:19 -07002231 // Let the new window know that the hover sequence is starting, unless we already did it
2232 // when dispatching it as is to newTouchedWindowHandle.
2233 if (newHoverWindowHandle != nullptr &&
2234 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2235 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002236 if (DEBUG_HOVER) {
2237 ALOGD("Sending hover enter event to window %s.",
2238 newHoverWindowHandle->getName().c_str());
2239 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002240 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2241 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2242 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002243 }
2244 }
2245
2246 // Check permission to inject into all touched foreground windows and ensure there
2247 // is at least one touched foreground window.
2248 {
2249 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002250 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002251 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2252 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002253 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002254 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002255 injectionPermission = INJECTION_PERMISSION_DENIED;
2256 goto Failed;
2257 }
2258 }
2259 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002260 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002261 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002262 ALOGI("Dropping event because there is no touched foreground window in display "
2263 "%" PRId32 " or gesture monitor to receive it.",
2264 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002265 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002266 goto Failed;
2267 }
2268
2269 // Permission granted to injection into all touched foreground windows.
2270 injectionPermission = INJECTION_PERMISSION_GRANTED;
2271 }
2272
2273 // Check whether windows listening for outside touches are owned by the same UID. If it is
2274 // set the policy flag that we will not reveal coordinate information to this window.
2275 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002276 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002277 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002278 if (foregroundWindowHandle) {
2279 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002280 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002281 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002282 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2283 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2284 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002285 InputTarget::FLAG_ZERO_COORDS,
2286 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002287 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002288 }
2289 }
2290 }
2291 }
2292
Michael Wrightd02c5b62014-02-10 15:10:22 -08002293 // If this is the first pointer going down and the touched window has a wallpaper
2294 // then also add the touched wallpaper windows so they are locked in for the duration
2295 // of the touch gesture.
2296 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2297 // engine only supports touch events. We would need to add a mechanism similar
2298 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2299 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002300 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002301 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002302 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
chaviw98318de2021-05-19 16:45:23 -05002303 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002304 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002305 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2306 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002307 if (info->displayId == displayId &&
chaviw98318de2021-05-19 16:45:23 -05002308 windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002309 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002310 .addOrUpdateWindow(windowHandle,
2311 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2312 InputTarget::
2313 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2314 InputTarget::FLAG_DISPATCH_AS_IS,
2315 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002316 }
2317 }
2318 }
2319 }
2320
2321 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002322 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002323
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002324 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002325 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002326 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002327 }
2328
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002329 for (const auto& monitor : tempTouchState.gestureMonitors) {
2330 addMonitoringTargetLocked(monitor, displayId, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002331 }
2332
Michael Wrightd02c5b62014-02-10 15:10:22 -08002333 // Drop the outside or hover touch windows since we will not care about them
2334 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002335 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002336
2337Failed:
2338 // Check injection permission once and for all.
2339 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002340 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002341 injectionPermission = INJECTION_PERMISSION_GRANTED;
2342 } else {
2343 injectionPermission = INJECTION_PERMISSION_DENIED;
2344 }
2345 }
2346
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002347 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2348 return injectionResult;
2349 }
2350
Michael Wrightd02c5b62014-02-10 15:10:22 -08002351 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002352 if (!wrongDevice) {
2353 if (switchedDevice) {
2354 if (DEBUG_FOCUS) {
2355 ALOGD("Conflicting pointer actions: Switched to a different device.");
2356 }
2357 *outConflictingPointerActions = true;
2358 }
2359
2360 if (isHoverAction) {
2361 // Started hovering, therefore no longer down.
2362 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002363 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002364 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2365 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002366 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002367 *outConflictingPointerActions = true;
2368 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002369 tempTouchState.reset();
2370 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2371 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2372 tempTouchState.deviceId = entry.deviceId;
2373 tempTouchState.source = entry.source;
2374 tempTouchState.displayId = displayId;
2375 }
2376 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2377 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2378 // All pointers up or canceled.
2379 tempTouchState.reset();
2380 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2381 // First pointer went down.
2382 if (oldState && oldState->down) {
2383 if (DEBUG_FOCUS) {
2384 ALOGD("Conflicting pointer actions: Down received while already down.");
2385 }
2386 *outConflictingPointerActions = true;
2387 }
2388 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2389 // One pointer went up.
2390 if (isSplit) {
2391 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2392 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002393
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002394 for (size_t i = 0; i < tempTouchState.windows.size();) {
2395 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2396 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2397 touchedWindow.pointerIds.clearBit(pointerId);
2398 if (touchedWindow.pointerIds.isEmpty()) {
2399 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2400 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002401 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002402 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002403 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002404 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002405 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002406 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002407
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002408 // Save changes unless the action was scroll in which case the temporary touch
2409 // state was only valid for this one action.
2410 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2411 if (tempTouchState.displayId >= 0) {
2412 mTouchStatesByDisplay[displayId] = tempTouchState;
2413 } else {
2414 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002415 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002416 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002417
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002418 // Update hover state.
2419 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002420 }
2421
Michael Wrightd02c5b62014-02-10 15:10:22 -08002422 return injectionResult;
2423}
2424
arthurhung6d4bed92021-03-17 11:59:33 +08002425void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
chaviw98318de2021-05-19 16:45:23 -05002426 const sp<WindowInfoHandle> dropWindow =
arthurhung6d4bed92021-03-17 11:59:33 +08002427 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002428 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002429 if (dropWindow) {
2430 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002431 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002432 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002433 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002434 }
2435 mDragState.reset();
2436}
2437
2438void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2439 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002440 return;
2441 }
2442
arthurhung6d4bed92021-03-17 11:59:33 +08002443 if (!mDragState->isStartDrag) {
2444 mDragState->isStartDrag = true;
2445 mDragState->isStylusButtonDownAtStart =
2446 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2447 }
2448
arthurhungb89ccb02020-12-30 16:19:01 +08002449 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2450 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2451 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2452 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002453 // Handle the special case : stylus button no longer pressed.
2454 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2455 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2456 finishDragAndDrop(entry.displayId, x, y);
2457 return;
2458 }
2459
chaviw98318de2021-05-19 16:45:23 -05002460 const sp<WindowInfoHandle> hoverWindowHandle =
arthurhung6d4bed92021-03-17 11:59:33 +08002461 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002462 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002463 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002464 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2465 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2466 if (mDragState->dragHoverWindowHandle != nullptr) {
2467 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2468 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002469 }
arthurhung6d4bed92021-03-17 11:59:33 +08002470 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002471 }
2472 // enqueue drag location if needed.
2473 if (hoverWindowHandle != nullptr) {
2474 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2475 }
arthurhung6d4bed92021-03-17 11:59:33 +08002476 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2477 finishDragAndDrop(entry.displayId, x, y);
2478 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002479 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002480 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002481 }
2482}
2483
chaviw98318de2021-05-19 16:45:23 -05002484void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002485 int32_t targetFlags, BitSet32 pointerIds,
2486 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002487 std::vector<InputTarget>::iterator it =
2488 std::find_if(inputTargets.begin(), inputTargets.end(),
2489 [&windowHandle](const InputTarget& inputTarget) {
2490 return inputTarget.inputChannel->getConnectionToken() ==
2491 windowHandle->getToken();
2492 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002493
chaviw98318de2021-05-19 16:45:23 -05002494 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002495
2496 if (it == inputTargets.end()) {
2497 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002498 std::shared_ptr<InputChannel> inputChannel =
2499 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002500 if (inputChannel == nullptr) {
2501 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2502 return;
2503 }
2504 inputTarget.inputChannel = inputChannel;
2505 inputTarget.flags = targetFlags;
2506 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002507 const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
2508 if (displayInfoIt != mDisplayInfos.end()) {
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002509 inputTarget.displayTransform = displayInfoIt->second.transform;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002510 } else {
2511 ALOGI_IF(isPerWindowInputRotationEnabled(),
2512 "DisplayInfo not found for window on display: %d", windowInfo->displayId);
2513 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002514 inputTargets.push_back(inputTarget);
2515 it = inputTargets.end() - 1;
2516 }
2517
2518 ALOG_ASSERT(it->flags == targetFlags);
2519 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2520
chaviw1ff3d1e2020-07-01 15:53:47 -07002521 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002522}
2523
Michael Wright3dd60e22019-03-27 22:06:44 +00002524void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002525 int32_t displayId) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002526 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2527 mGlobalMonitorsByDisplay.find(displayId);
2528
2529 if (it != mGlobalMonitorsByDisplay.end()) {
2530 const std::vector<Monitor>& monitors = it->second;
2531 for (const Monitor& monitor : monitors) {
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002532 addMonitoringTargetLocked(monitor, displayId, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002533 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002534 }
2535}
2536
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002537void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, int32_t displayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002538 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002539 InputTarget target;
2540 target.inputChannel = monitor.inputChannel;
2541 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002542 ui::Transform t;
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002543 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
2544 // Input monitors always get un-rotated display coordinates. We undo the display
2545 // rotation that is present in the display transform so that display rotation is not
2546 // applied to these input targets.
2547 const auto& displayInfo = it->second;
2548 int32_t width = displayInfo.logicalWidth;
2549 int32_t height = displayInfo.logicalHeight;
2550 const auto orientation = displayInfo.transform.getOrientation();
2551 uint32_t inverseOrientation = orientation;
2552 if (orientation == ui::Transform::ROT_90) {
2553 inverseOrientation = ui::Transform::ROT_270;
2554 std::swap(width, height);
2555 } else if (orientation == ui::Transform::ROT_270) {
2556 inverseOrientation = ui::Transform::ROT_90;
2557 std::swap(width, height);
2558 }
2559 target.displayTransform =
2560 ui::Transform(inverseOrientation, width, height) * displayInfo.transform;
2561 t = t * target.displayTransform;
2562 }
chaviw1ff3d1e2020-07-01 15:53:47 -07002563 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002564 inputTargets.push_back(target);
2565}
2566
chaviw98318de2021-05-19 16:45:23 -05002567bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002568 const InjectionState* injectionState) {
2569 if (injectionState &&
2570 (windowHandle == nullptr ||
2571 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2572 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002573 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002574 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002575 "owned by uid %d",
2576 injectionState->injectorPid, injectionState->injectorUid,
2577 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002578 } else {
2579 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002580 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002581 }
2582 return false;
2583 }
2584 return true;
2585}
2586
Robert Carrc9bf1d32020-04-13 17:21:08 -07002587/**
2588 * Indicate whether one window handle should be considered as obscuring
2589 * another window handle. We only check a few preconditions. Actually
2590 * checking the bounds is left to the caller.
2591 */
chaviw98318de2021-05-19 16:45:23 -05002592static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2593 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002594 // Compare by token so cloned layers aren't counted
2595 if (haveSameToken(windowHandle, otherHandle)) {
2596 return false;
2597 }
2598 auto info = windowHandle->getInfo();
2599 auto otherInfo = otherHandle->getInfo();
2600 if (!otherInfo->visible) {
2601 return false;
chaviw98318de2021-05-19 16:45:23 -05002602 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002603 // Those act as if they were invisible, so we don't need to flag them.
2604 // We do want to potentially flag touchable windows even if they have 0
2605 // opacity, since they can consume touches and alter the effects of the
2606 // user interaction (eg. apps that rely on
2607 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2608 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2609 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002610 } else if (info->ownerUid == otherInfo->ownerUid) {
2611 // If ownerUid is the same we don't generate occlusion events as there
2612 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002613 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002614 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002615 return false;
2616 } else if (otherInfo->displayId != info->displayId) {
2617 return false;
2618 }
2619 return true;
2620}
2621
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002622/**
2623 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2624 * untrusted, one should check:
2625 *
2626 * 1. If result.hasBlockingOcclusion is true.
2627 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2628 * BLOCK_UNTRUSTED.
2629 *
2630 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2631 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2632 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2633 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2634 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2635 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2636 *
2637 * If neither of those is true, then it means the touch can be allowed.
2638 */
2639InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002640 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2641 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002642 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002643 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002644 TouchOcclusionInfo info;
2645 info.hasBlockingOcclusion = false;
2646 info.obscuringOpacity = 0;
2647 info.obscuringUid = -1;
2648 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002649 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002650 if (windowHandle == otherHandle) {
2651 break; // All future windows are below us. Exit early.
2652 }
chaviw98318de2021-05-19 16:45:23 -05002653 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002654 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2655 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002656 if (DEBUG_TOUCH_OCCLUSION) {
2657 info.debugInfo.push_back(
2658 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2659 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002660 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2661 // we perform the checks below to see if the touch can be propagated or not based on the
2662 // window's touch occlusion mode
2663 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2664 info.hasBlockingOcclusion = true;
2665 info.obscuringUid = otherInfo->ownerUid;
2666 info.obscuringPackage = otherInfo->packageName;
2667 break;
2668 }
2669 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2670 uint32_t uid = otherInfo->ownerUid;
2671 float opacity =
2672 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2673 // Given windows A and B:
2674 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2675 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2676 opacityByUid[uid] = opacity;
2677 if (opacity > info.obscuringOpacity) {
2678 info.obscuringOpacity = opacity;
2679 info.obscuringUid = uid;
2680 info.obscuringPackage = otherInfo->packageName;
2681 }
2682 }
2683 }
2684 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002685 if (DEBUG_TOUCH_OCCLUSION) {
2686 info.debugInfo.push_back(
2687 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2688 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002689 return info;
2690}
2691
chaviw98318de2021-05-19 16:45:23 -05002692std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002693 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002694 return StringPrintf(INDENT2
2695 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2696 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2697 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2698 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Dominik Laskowski75788452021-02-09 18:51:25 -08002699 isTouchedWindow ? "[TOUCHED] " : "", ftl::enum_string(info->type).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002700 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002701 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2702 info->frameTop, info->frameRight, info->frameBottom,
2703 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002704 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2705 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2706 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002707}
2708
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002709bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2710 if (occlusionInfo.hasBlockingOcclusion) {
2711 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2712 occlusionInfo.obscuringUid);
2713 return false;
2714 }
2715 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2716 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2717 "%.2f, maximum allowed = %.2f)",
2718 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2719 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2720 return false;
2721 }
2722 return true;
2723}
2724
chaviw98318de2021-05-19 16:45:23 -05002725bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002726 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002727 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002728 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2729 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002730 if (windowHandle == otherHandle) {
2731 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002732 }
chaviw98318de2021-05-19 16:45:23 -05002733 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002734 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002735 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002736 return true;
2737 }
2738 }
2739 return false;
2740}
2741
chaviw98318de2021-05-19 16:45:23 -05002742bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002743 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002744 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2745 const WindowInfo* windowInfo = windowHandle->getInfo();
2746 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002747 if (windowHandle == otherHandle) {
2748 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002749 }
chaviw98318de2021-05-19 16:45:23 -05002750 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002751 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002752 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002753 return true;
2754 }
2755 }
2756 return false;
2757}
2758
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002759std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002760 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002761 if (applicationHandle != nullptr) {
2762 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002763 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002764 } else {
2765 return applicationHandle->getName();
2766 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002767 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002768 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002769 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002770 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002771 }
2772}
2773
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002774void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002775 if (eventEntry.type == EventEntry::Type::FOCUS ||
arthurhungb89ccb02020-12-30 16:19:01 +08002776 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED ||
2777 eventEntry.type == EventEntry::Type::DRAG) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002778 // Focus or pointer capture changed events are passed to apps, but do not represent user
2779 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002780 return;
2781 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002782 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002783 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002784 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002785 const WindowInfo* info = focusedWindowHandle->getInfo();
2786 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002787 if (DEBUG_DISPATCH_CYCLE) {
2788 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2789 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002790 return;
2791 }
2792 }
2793
2794 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002795 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002796 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002797 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2798 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002799 return;
2800 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002801
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002802 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002803 eventType = USER_ACTIVITY_EVENT_TOUCH;
2804 }
2805 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002806 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002807 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002808 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2809 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002810 return;
2811 }
2812 eventType = USER_ACTIVITY_EVENT_BUTTON;
2813 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002814 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07002815 case EventEntry::Type::TOUCH_MODE_CHANGED: {
2816 break;
2817 }
2818
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002819 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002820 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002821 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002822 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08002823 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2824 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002825 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08002826 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002827 break;
2828 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002829 }
2830
Prabir Pradhancef936d2021-07-21 16:17:52 +00002831 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2832 REQUIRES(mLock) {
2833 scoped_unlock unlock(mLock);
2834 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2835 };
2836 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002837}
2838
2839void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002840 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002841 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002842 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002843 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002844 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002845 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002846 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002847 ATRACE_NAME(message.c_str());
2848 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002849 if (DEBUG_DISPATCH_CYCLE) {
2850 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2851 "globalScaleFactor=%f, pointerIds=0x%x %s",
2852 connection->getInputChannelName().c_str(), inputTarget.flags,
2853 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2854 inputTarget.getPointerInfoString().c_str());
2855 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002856
2857 // Skip this event if the connection status is not normal.
2858 // We don't want to enqueue additional outbound events if the connection is broken.
2859 if (connection->status != Connection::STATUS_NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002860 if (DEBUG_DISPATCH_CYCLE) {
2861 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
2862 connection->getInputChannelName().c_str(), connection->getStatusLabel());
2863 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002864 return;
2865 }
2866
2867 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002868 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2869 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2870 "Entry type %s should not have FLAG_SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08002871 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002872
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002873 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002874 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002875 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002876 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002877 if (!splitMotionEntry) {
2878 return; // split event was dropped
2879 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002880 if (DEBUG_FOCUS) {
2881 ALOGD("channel '%s' ~ Split motion event.",
2882 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002883 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002884 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002885 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2886 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002887 return;
2888 }
2889 }
2890
2891 // Not splitting. Enqueue dispatch entries for the event as is.
2892 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2893}
2894
2895void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002896 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002897 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002898 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002899 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002900 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002901 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002902 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002903 ATRACE_NAME(message.c_str());
2904 }
2905
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002906 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002907
2908 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002909 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002910 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002911 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002912 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002913 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002914 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002915 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002916 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002917 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002918 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002919 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002920 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002921
2922 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002923 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924 startDispatchCycleLocked(currentTime, connection);
2925 }
2926}
2927
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002928void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002929 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002930 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002931 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002932 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002933 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2934 connection->getInputChannelName().c_str(),
2935 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002936 ATRACE_NAME(message.c_str());
2937 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002938 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002939 if (!(inputTargetFlags & dispatchMode)) {
2940 return;
2941 }
2942 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2943
2944 // This is a new event.
2945 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002946 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002947 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002948
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002949 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2950 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002951 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002952 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002953 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002954 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002955 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002956 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002957 dispatchEntry->resolvedAction = keyEntry.action;
2958 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002959
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002960 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2961 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002962 if (DEBUG_DISPATCH_CYCLE) {
2963 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
2964 "event",
2965 connection->getInputChannelName().c_str());
2966 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002967 return; // skip the inconsistent event
2968 }
2969 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002970 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002971
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002972 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002973 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002974 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2975 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2976 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2977 static_cast<int32_t>(IdGenerator::Source::OTHER);
2978 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002979 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2980 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2981 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2982 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2983 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2984 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2985 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2986 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2987 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2988 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2989 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002990 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002991 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002992 }
2993 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002994 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2995 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002996 if (DEBUG_DISPATCH_CYCLE) {
2997 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
2998 "enter event",
2999 connection->getInputChannelName().c_str());
3000 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003001 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
3002 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003003 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3004 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003005
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003006 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003007 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
3008 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3009 }
3010 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
3011 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3012 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003013
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003014 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
3015 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003016 if (DEBUG_DISPATCH_CYCLE) {
3017 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
3018 "event",
3019 connection->getInputChannelName().c_str());
3020 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003021 return; // skip the inconsistent event
3022 }
3023
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003024 dispatchEntry->resolvedEventId =
3025 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
3026 ? mIdGenerator.nextId()
3027 : motionEntry.id;
3028 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
3029 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3030 ") to MotionEvent(id=0x%" PRIx32 ").",
3031 motionEntry.id, dispatchEntry->resolvedEventId);
3032 ATRACE_NAME(message.c_str());
3033 }
3034
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003035 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3036 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
3037 // Skip reporting pointer down outside focus to the policy.
3038 break;
3039 }
3040
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003041 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003042 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003043
3044 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003045 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003046 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003047 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003048 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3049 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003050 break;
3051 }
Chris Yef59a2f42020-10-16 12:55:26 -07003052 case EventEntry::Type::SENSOR: {
3053 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3054 break;
3055 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003056 case EventEntry::Type::CONFIGURATION_CHANGED:
3057 case EventEntry::Type::DEVICE_RESET: {
3058 LOG_ALWAYS_FATAL("%s events should not go to apps",
Dominik Laskowski75788452021-02-09 18:51:25 -08003059 ftl::enum_string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003060 break;
3061 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003062 }
3063
3064 // Remember that we are waiting for this dispatch to complete.
3065 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003066 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003067 }
3068
3069 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003070 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003071 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003072}
3073
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003074/**
3075 * This function is purely for debugging. It helps us understand where the user interaction
3076 * was taking place. For example, if user is touching launcher, we will see a log that user
3077 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3078 * We will see both launcher and wallpaper in that list.
3079 * Once the interaction with a particular set of connections starts, no new logs will be printed
3080 * until the set of interacted connections changes.
3081 *
3082 * The following items are skipped, to reduce the logspam:
3083 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3084 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3085 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3086 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3087 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003088 */
3089void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3090 const std::vector<InputTarget>& targets) {
3091 // Skip ACTION_UP events, and all events other than keys and motions
3092 if (entry.type == EventEntry::Type::KEY) {
3093 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3094 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3095 return;
3096 }
3097 } else if (entry.type == EventEntry::Type::MOTION) {
3098 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3099 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3100 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3101 return;
3102 }
3103 } else {
3104 return; // Not a key or a motion
3105 }
3106
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003107 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003108 std::vector<sp<Connection>> newConnections;
3109 for (const InputTarget& target : targets) {
3110 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3111 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3112 continue; // Skip windows that receive ACTION_OUTSIDE
3113 }
3114
3115 sp<IBinder> token = target.inputChannel->getConnectionToken();
3116 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003117 if (connection == nullptr) {
3118 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003119 }
3120 newConnectionTokens.insert(std::move(token));
3121 newConnections.emplace_back(connection);
3122 }
3123 if (newConnectionTokens == mInteractionConnectionTokens) {
3124 return; // no change
3125 }
3126 mInteractionConnectionTokens = newConnectionTokens;
3127
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003128 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003129 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003130 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003131 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003132 std::string message = "Interaction with: " + targetList;
3133 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003134 message += "<none>";
3135 }
3136 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3137}
3138
chaviwfd6d3512019-03-25 13:23:49 -07003139void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003140 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003141 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003142 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3143 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003144 return;
3145 }
3146
Vishnu Nairc519ff72021-01-21 08:23:08 -08003147 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003148 if (focusedToken == token) {
3149 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003150 return;
3151 }
3152
Prabir Pradhancef936d2021-07-21 16:17:52 +00003153 auto command = [this, token]() REQUIRES(mLock) {
3154 scoped_unlock unlock(mLock);
3155 mPolicy->onPointerDownOutsideFocus(token);
3156 };
3157 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003158}
3159
3160void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003161 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003162 if (ATRACE_ENABLED()) {
3163 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003164 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003165 ATRACE_NAME(message.c_str());
3166 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003167 if (DEBUG_DISPATCH_CYCLE) {
3168 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3169 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003170
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003171 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3172 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003173 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003174 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003175 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003176 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003177
3178 // Publish the event.
3179 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003180 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3181 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003182 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003183 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3184 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003185
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003186 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003187 status = connection->inputPublisher
3188 .publishKeyEvent(dispatchEntry->seq,
3189 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3190 keyEntry.source, keyEntry.displayId,
3191 std::move(hmac), dispatchEntry->resolvedAction,
3192 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3193 keyEntry.scanCode, keyEntry.metaState,
3194 keyEntry.repeatCount, keyEntry.downTime,
3195 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003196 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003197 }
3198
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003199 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003200 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003201
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003202 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003203 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003204
chaviw82357092020-01-28 13:13:06 -08003205 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003206 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003207 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3208 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003209 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003210 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3211 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003212 // Don't apply window scale here since we don't want scale to affect raw
3213 // coordinates. The scale will be sent back to the client and applied
3214 // later when requesting relative coordinates.
3215 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3216 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003217 }
3218 usingCoords = scaledCoords;
3219 }
3220 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003221 // We don't want the dispatch target to know.
3222 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003223 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003224 scaledCoords[i].clear();
3225 }
3226 usingCoords = scaledCoords;
3227 }
3228 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003229
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003230 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003231
3232 // Publish the motion event.
3233 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003234 .publishMotionEvent(dispatchEntry->seq,
3235 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003236 motionEntry.deviceId, motionEntry.source,
3237 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003238 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003239 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003240 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003241 motionEntry.edgeFlags, motionEntry.metaState,
3242 motionEntry.buttonState,
3243 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003244 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003245 motionEntry.xPrecision, motionEntry.yPrecision,
3246 motionEntry.xCursorPosition,
3247 motionEntry.yCursorPosition,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003248 dispatchEntry->rawTransform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003249 motionEntry.downTime, motionEntry.eventTime,
3250 motionEntry.pointerCount,
3251 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003252 break;
3253 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003254
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003255 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003256 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003257 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003258 focusEntry.id,
3259 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003260 mInTouchMode);
3261 break;
3262 }
3263
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003264 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3265 const TouchModeEntry& touchModeEntry =
3266 static_cast<const TouchModeEntry&>(eventEntry);
3267 status = connection->inputPublisher
3268 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3269 touchModeEntry.inTouchMode);
3270
3271 break;
3272 }
3273
Prabir Pradhan99987712020-11-10 18:43:05 -08003274 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3275 const auto& captureEntry =
3276 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3277 status = connection->inputPublisher
3278 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003279 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003280 break;
3281 }
3282
arthurhungb89ccb02020-12-30 16:19:01 +08003283 case EventEntry::Type::DRAG: {
3284 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3285 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3286 dragEntry.id, dragEntry.x,
3287 dragEntry.y,
3288 dragEntry.isExiting);
3289 break;
3290 }
3291
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003292 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003293 case EventEntry::Type::DEVICE_RESET:
3294 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003295 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003296 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003297 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003298 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003299 }
3300
3301 // Check the result.
3302 if (status) {
3303 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003304 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003305 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003306 "This is unexpected because the wait queue is empty, so the pipe "
3307 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003308 "event to it, status=%s(%d)",
3309 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3310 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003311 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3312 } else {
3313 // Pipe is full and we are waiting for the app to finish process some events
3314 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003315 if (DEBUG_DISPATCH_CYCLE) {
3316 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3317 "waiting for the application to catch up",
3318 connection->getInputChannelName().c_str());
3319 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003320 }
3321 } else {
3322 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003323 "status=%s(%d)",
3324 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3325 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003326 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3327 }
3328 return;
3329 }
3330
3331 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003332 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3333 connection->outboundQueue.end(),
3334 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003335 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003336 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003337 if (connection->responsive) {
3338 mAnrTracker.insert(dispatchEntry->timeoutTime,
3339 connection->inputChannel->getConnectionToken());
3340 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003341 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003342 }
3343}
3344
chaviw09c8d2d2020-08-24 15:48:26 -07003345std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3346 size_t size;
3347 switch (event.type) {
3348 case VerifiedInputEvent::Type::KEY: {
3349 size = sizeof(VerifiedKeyEvent);
3350 break;
3351 }
3352 case VerifiedInputEvent::Type::MOTION: {
3353 size = sizeof(VerifiedMotionEvent);
3354 break;
3355 }
3356 }
3357 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3358 return mHmacKeyManager.sign(start, size);
3359}
3360
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003361const std::array<uint8_t, 32> InputDispatcher::getSignature(
3362 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3363 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3364 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3365 // Only sign events up and down events as the purely move events
3366 // are tied to their up/down counterparts so signing would be redundant.
3367 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3368 verifiedEvent.actionMasked = actionMasked;
3369 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003370 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003371 }
3372 return INVALID_HMAC;
3373}
3374
3375const std::array<uint8_t, 32> InputDispatcher::getSignature(
3376 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3377 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3378 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3379 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003380 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003381}
3382
Michael Wrightd02c5b62014-02-10 15:10:22 -08003383void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003384 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003385 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003386 if (DEBUG_DISPATCH_CYCLE) {
3387 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3388 connection->getInputChannelName().c_str(), seq, toString(handled));
3389 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003390
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003391 if (connection->status == Connection::STATUS_BROKEN ||
3392 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003393 return;
3394 }
3395
3396 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003397 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3398 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3399 };
3400 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003401}
3402
3403void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003404 const sp<Connection>& connection,
3405 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003406 if (DEBUG_DISPATCH_CYCLE) {
3407 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3408 connection->getInputChannelName().c_str(), toString(notify));
3409 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003410
3411 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003412 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003413 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003414 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003415 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003416
3417 // The connection appears to be unrecoverably broken.
3418 // Ignore already broken or zombie connections.
3419 if (connection->status == Connection::STATUS_NORMAL) {
3420 connection->status = Connection::STATUS_BROKEN;
3421
3422 if (notify) {
3423 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003424 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3425 connection->getInputChannelName().c_str());
3426
3427 auto command = [this, connection]() REQUIRES(mLock) {
3428 if (connection->status == Connection::STATUS_ZOMBIE) return;
3429 scoped_unlock unlock(mLock);
3430 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3431 };
3432 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003433 }
3434 }
3435}
3436
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003437void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3438 while (!queue.empty()) {
3439 DispatchEntry* dispatchEntry = queue.front();
3440 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003441 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003442 }
3443}
3444
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003445void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003446 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003447 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003448 }
3449 delete dispatchEntry;
3450}
3451
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003452int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3453 std::scoped_lock _l(mLock);
3454 sp<Connection> connection = getConnectionLocked(connectionToken);
3455 if (connection == nullptr) {
3456 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3457 connectionToken.get(), events);
3458 return 0; // remove the callback
3459 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003460
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003461 bool notify;
3462 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3463 if (!(events & ALOOPER_EVENT_INPUT)) {
3464 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3465 "events=0x%x",
3466 connection->getInputChannelName().c_str(), events);
3467 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003468 }
3469
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003470 nsecs_t currentTime = now();
3471 bool gotOne = false;
3472 status_t status = OK;
3473 for (;;) {
3474 Result<InputPublisher::ConsumerResponse> result =
3475 connection->inputPublisher.receiveConsumerResponse();
3476 if (!result.ok()) {
3477 status = result.error().code();
3478 break;
3479 }
3480
3481 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3482 const InputPublisher::Finished& finish =
3483 std::get<InputPublisher::Finished>(*result);
3484 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3485 finish.consumeTime);
3486 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003487 if (shouldReportMetricsForConnection(*connection)) {
3488 const InputPublisher::Timeline& timeline =
3489 std::get<InputPublisher::Timeline>(*result);
3490 mLatencyTracker
3491 .trackGraphicsLatency(timeline.inputEventId,
3492 connection->inputChannel->getConnectionToken(),
3493 std::move(timeline.graphicsTimeline));
3494 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003495 }
3496 gotOne = true;
3497 }
3498 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003499 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003500 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003501 return 1;
3502 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003503 }
3504
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003505 notify = status != DEAD_OBJECT || !connection->monitor;
3506 if (notify) {
3507 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3508 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3509 status);
3510 }
3511 } else {
3512 // Monitor channels are never explicitly unregistered.
3513 // We do it automatically when the remote endpoint is closed so don't warn about them.
3514 const bool stillHaveWindowHandle =
3515 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3516 notify = !connection->monitor && stillHaveWindowHandle;
3517 if (notify) {
3518 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3519 connection->getInputChannelName().c_str(), events);
3520 }
3521 }
3522
3523 // Remove the channel.
3524 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3525 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003526}
3527
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003528void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003529 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003530 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003531 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003532 }
3533}
3534
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003535void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003536 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003537 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3538 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3539}
3540
3541void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3542 const CancelationOptions& options,
3543 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3544 for (const auto& it : monitorsByDisplay) {
3545 const std::vector<Monitor>& monitors = it.second;
3546 for (const Monitor& monitor : monitors) {
3547 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003548 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003549 }
3550}
3551
Michael Wrightd02c5b62014-02-10 15:10:22 -08003552void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003553 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003554 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003555 if (connection == nullptr) {
3556 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003557 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003558
3559 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003560}
3561
3562void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3563 const sp<Connection>& connection, const CancelationOptions& options) {
3564 if (connection->status == Connection::STATUS_BROKEN) {
3565 return;
3566 }
3567
3568 nsecs_t currentTime = now();
3569
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003570 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003571 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003572
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003573 if (cancelationEvents.empty()) {
3574 return;
3575 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003576 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3577 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3578 "with reality: %s, mode=%d.",
3579 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3580 options.mode);
3581 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003582
3583 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003584 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003585 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3586 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003587 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003588 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003589 target.globalScaleFactor = windowInfo->globalScaleFactor;
3590 }
3591 target.inputChannel = connection->inputChannel;
3592 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3593
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003594 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003595 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003596 switch (cancelationEventEntry->type) {
3597 case EventEntry::Type::KEY: {
3598 logOutboundKeyDetails("cancel - ",
3599 static_cast<const KeyEntry&>(*cancelationEventEntry));
3600 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003601 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003602 case EventEntry::Type::MOTION: {
3603 logOutboundMotionDetails("cancel - ",
3604 static_cast<const MotionEntry&>(*cancelationEventEntry));
3605 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003606 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003607 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003608 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003609 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3610 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003611 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08003612 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003613 break;
3614 }
3615 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003616 case EventEntry::Type::DEVICE_RESET:
3617 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003618 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003619 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003620 break;
3621 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003622 }
3623
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003624 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3625 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003626 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003627
3628 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003629}
3630
Svet Ganov5d3bc372020-01-26 23:11:07 -08003631void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3632 const sp<Connection>& connection) {
3633 if (connection->status == Connection::STATUS_BROKEN) {
3634 return;
3635 }
3636
3637 nsecs_t currentTime = now();
3638
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003639 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003640 connection->inputState.synthesizePointerDownEvents(currentTime);
3641
3642 if (downEvents.empty()) {
3643 return;
3644 }
3645
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003646 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003647 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3648 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003649 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003650
3651 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003652 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003653 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3654 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003655 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003656 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003657 target.globalScaleFactor = windowInfo->globalScaleFactor;
3658 }
3659 target.inputChannel = connection->inputChannel;
3660 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3661
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003662 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003663 switch (downEventEntry->type) {
3664 case EventEntry::Type::MOTION: {
3665 logOutboundMotionDetails("down - ",
3666 static_cast<const MotionEntry&>(*downEventEntry));
3667 break;
3668 }
3669
3670 case EventEntry::Type::KEY:
3671 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003672 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08003673 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003674 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003675 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003676 case EventEntry::Type::SENSOR:
3677 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003678 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003679 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003680 break;
3681 }
3682 }
3683
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003684 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3685 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003686 }
3687
3688 startDispatchCycleLocked(currentTime, connection);
3689}
3690
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003691std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3692 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003693 ALOG_ASSERT(pointerIds.value != 0);
3694
3695 uint32_t splitPointerIndexMap[MAX_POINTERS];
3696 PointerProperties splitPointerProperties[MAX_POINTERS];
3697 PointerCoords splitPointerCoords[MAX_POINTERS];
3698
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003699 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003700 uint32_t splitPointerCount = 0;
3701
3702 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003703 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003704 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003705 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003706 uint32_t pointerId = uint32_t(pointerProperties.id);
3707 if (pointerIds.hasBit(pointerId)) {
3708 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3709 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3710 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003711 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003712 splitPointerCount += 1;
3713 }
3714 }
3715
3716 if (splitPointerCount != pointerIds.count()) {
3717 // This is bad. We are missing some of the pointers that we expected to deliver.
3718 // Most likely this indicates that we received an ACTION_MOVE events that has
3719 // different pointer ids than we expected based on the previous ACTION_DOWN
3720 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3721 // in this way.
3722 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003723 "we expected there to be %d pointers. This probably means we received "
3724 "a broken sequence of pointer ids from the input device.",
3725 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003726 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003727 }
3728
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003729 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003730 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003731 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3732 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003733 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3734 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003735 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003736 uint32_t pointerId = uint32_t(pointerProperties.id);
3737 if (pointerIds.hasBit(pointerId)) {
3738 if (pointerIds.count() == 1) {
3739 // The first/last pointer went down/up.
3740 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003741 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003742 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3743 ? AMOTION_EVENT_ACTION_CANCEL
3744 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003745 } else {
3746 // A secondary pointer went down/up.
3747 uint32_t splitPointerIndex = 0;
3748 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3749 splitPointerIndex += 1;
3750 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003751 action = maskedAction |
3752 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003753 }
3754 } else {
3755 // An unrelated pointer changed.
3756 action = AMOTION_EVENT_ACTION_MOVE;
3757 }
3758 }
3759
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003760 int32_t newId = mIdGenerator.nextId();
3761 if (ATRACE_ENABLED()) {
3762 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3763 ") to MotionEvent(id=0x%" PRIx32 ").",
3764 originalMotionEntry.id, newId);
3765 ATRACE_NAME(message.c_str());
3766 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003767 std::unique_ptr<MotionEntry> splitMotionEntry =
3768 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3769 originalMotionEntry.deviceId, originalMotionEntry.source,
3770 originalMotionEntry.displayId,
3771 originalMotionEntry.policyFlags, action,
3772 originalMotionEntry.actionButton,
3773 originalMotionEntry.flags, originalMotionEntry.metaState,
3774 originalMotionEntry.buttonState,
3775 originalMotionEntry.classification,
3776 originalMotionEntry.edgeFlags,
3777 originalMotionEntry.xPrecision,
3778 originalMotionEntry.yPrecision,
3779 originalMotionEntry.xCursorPosition,
3780 originalMotionEntry.yCursorPosition,
3781 originalMotionEntry.downTime, splitPointerCount,
3782 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003783
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003784 if (originalMotionEntry.injectionState) {
3785 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003786 splitMotionEntry->injectionState->refCount += 1;
3787 }
3788
3789 return splitMotionEntry;
3790}
3791
3792void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003793 if (DEBUG_INBOUND_EVENT_DETAILS) {
3794 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3795 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003796
3797 bool needWake;
3798 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003799 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003800
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003801 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3802 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3803 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003804 } // release lock
3805
3806 if (needWake) {
3807 mLooper->wake();
3808 }
3809}
3810
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003811/**
3812 * If one of the meta shortcuts is detected, process them here:
3813 * Meta + Backspace -> generate BACK
3814 * Meta + Enter -> generate HOME
3815 * This will potentially overwrite keyCode and metaState.
3816 */
3817void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003818 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003819 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3820 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3821 if (keyCode == AKEYCODE_DEL) {
3822 newKeyCode = AKEYCODE_BACK;
3823 } else if (keyCode == AKEYCODE_ENTER) {
3824 newKeyCode = AKEYCODE_HOME;
3825 }
3826 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003827 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003828 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003829 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003830 keyCode = newKeyCode;
3831 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3832 }
3833 } else if (action == AKEY_EVENT_ACTION_UP) {
3834 // In order to maintain a consistent stream of up and down events, check to see if the key
3835 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3836 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003837 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003838 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003839 auto replacementIt = mReplacedKeys.find(replacement);
3840 if (replacementIt != mReplacedKeys.end()) {
3841 keyCode = replacementIt->second;
3842 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003843 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3844 }
3845 }
3846}
3847
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003849 if (DEBUG_INBOUND_EVENT_DETAILS) {
3850 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3851 "policyFlags=0x%x, action=0x%x, "
3852 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3853 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3854 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3855 args->downTime);
3856 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003857 if (!validateKeyEvent(args->action)) {
3858 return;
3859 }
3860
3861 uint32_t policyFlags = args->policyFlags;
3862 int32_t flags = args->flags;
3863 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003864 // InputDispatcher tracks and generates key repeats on behalf of
3865 // whatever notifies it, so repeatCount should always be set to 0
3866 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003867 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3868 policyFlags |= POLICY_FLAG_VIRTUAL;
3869 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3870 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003871 if (policyFlags & POLICY_FLAG_FUNCTION) {
3872 metaState |= AMETA_FUNCTION_ON;
3873 }
3874
3875 policyFlags |= POLICY_FLAG_TRUSTED;
3876
Michael Wright78f24442014-08-06 15:55:28 -07003877 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003878 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003879
Michael Wrightd02c5b62014-02-10 15:10:22 -08003880 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003881 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003882 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3883 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003884
Michael Wright2b3c3302018-03-02 17:19:13 +00003885 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003886 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003887 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3888 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003889 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003890 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003891
Michael Wrightd02c5b62014-02-10 15:10:22 -08003892 bool needWake;
3893 { // acquire lock
3894 mLock.lock();
3895
3896 if (shouldSendKeyToInputFilterLocked(args)) {
3897 mLock.unlock();
3898
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003899 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003900 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3901 return; // event was consumed by the filter
3902 }
3903
3904 mLock.lock();
3905 }
3906
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003907 std::unique_ptr<KeyEntry> newEntry =
3908 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3909 args->displayId, policyFlags, args->action, flags,
3910 keyCode, args->scanCode, metaState, repeatCount,
3911 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003912
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003913 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003914 mLock.unlock();
3915 } // release lock
3916
3917 if (needWake) {
3918 mLooper->wake();
3919 }
3920}
3921
3922bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3923 return mInputFilterEnabled;
3924}
3925
3926void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003927 if (DEBUG_INBOUND_EVENT_DETAILS) {
3928 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3929 "displayId=%" PRId32 ", policyFlags=0x%x, "
3930 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3931 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
3932 "yCursorPosition=%f, downTime=%" PRId64,
3933 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3934 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3935 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3936 args->xCursorPosition, args->yCursorPosition, args->downTime);
3937 for (uint32_t i = 0; i < args->pointerCount; i++) {
3938 ALOGD(" Pointer %d: id=%d, toolType=%d, "
3939 "x=%f, y=%f, pressure=%f, size=%f, "
3940 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3941 "orientation=%f",
3942 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3943 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3944 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3945 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3946 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3947 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3948 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3949 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3950 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3951 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
3952 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003953 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003954 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3955 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003956 return;
3957 }
3958
3959 uint32_t policyFlags = args->policyFlags;
3960 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003961
3962 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003963 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003964 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3965 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003966 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003967 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003968
3969 bool needWake;
3970 { // acquire lock
3971 mLock.lock();
3972
3973 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07003974 ui::Transform displayTransform;
3975 if (const auto it = mDisplayInfos.find(args->displayId); it != mDisplayInfos.end()) {
3976 displayTransform = it->second.transform;
3977 }
3978
Michael Wrightd02c5b62014-02-10 15:10:22 -08003979 mLock.unlock();
3980
3981 MotionEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003982 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3983 args->action, args->actionButton, args->flags, args->edgeFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003984 args->metaState, args->buttonState, args->classification,
Prabir Pradhan81420cc2021-09-06 10:28:50 -07003985 displayTransform, args->xPrecision, args->yPrecision,
3986 args->xCursorPosition, args->yCursorPosition, displayTransform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003987 args->downTime, args->eventTime, args->pointerCount,
3988 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003989
3990 policyFlags |= POLICY_FLAG_FILTERED;
3991 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3992 return; // event was consumed by the filter
3993 }
3994
3995 mLock.lock();
3996 }
3997
3998 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003999 std::unique_ptr<MotionEntry> newEntry =
4000 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
4001 args->source, args->displayId, policyFlags,
4002 args->action, args->actionButton, args->flags,
4003 args->metaState, args->buttonState,
4004 args->classification, args->edgeFlags,
4005 args->xPrecision, args->yPrecision,
4006 args->xCursorPosition, args->yCursorPosition,
4007 args->downTime, args->pointerCount,
4008 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004009
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004010 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4011 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
4012 !mInputFilterEnabled) {
4013 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
4014 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
4015 }
4016
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004017 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004018 mLock.unlock();
4019 } // release lock
4020
4021 if (needWake) {
4022 mLooper->wake();
4023 }
4024}
4025
Chris Yef59a2f42020-10-16 12:55:26 -07004026void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004027 if (DEBUG_INBOUND_EVENT_DETAILS) {
4028 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4029 " sensorType=%s",
4030 args->id, args->eventTime, args->deviceId, args->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08004031 ftl::enum_string(args->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004032 }
Chris Yef59a2f42020-10-16 12:55:26 -07004033
4034 bool needWake;
4035 { // acquire lock
4036 mLock.lock();
4037
4038 // Just enqueue a new sensor event.
4039 std::unique_ptr<SensorEntry> newEntry =
4040 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
4041 args->source, 0 /* policyFlags*/, args->hwTimestamp,
4042 args->sensorType, args->accuracy,
4043 args->accuracyChanged, args->values);
4044
4045 needWake = enqueueInboundEventLocked(std::move(newEntry));
4046 mLock.unlock();
4047 } // release lock
4048
4049 if (needWake) {
4050 mLooper->wake();
4051 }
4052}
4053
Chris Yefb552902021-02-03 17:18:37 -08004054void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004055 if (DEBUG_INBOUND_EVENT_DETAILS) {
4056 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
4057 args->deviceId, args->isOn);
4058 }
Chris Yefb552902021-02-03 17:18:37 -08004059 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
4060}
4061
Michael Wrightd02c5b62014-02-10 15:10:22 -08004062bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08004063 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004064}
4065
4066void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004067 if (DEBUG_INBOUND_EVENT_DETAILS) {
4068 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4069 "switchMask=0x%08x",
4070 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
4071 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004072
4073 uint32_t policyFlags = args->policyFlags;
4074 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004075 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004076}
4077
4078void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004079 if (DEBUG_INBOUND_EVENT_DETAILS) {
4080 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
4081 args->deviceId);
4082 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004083
4084 bool needWake;
4085 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004086 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004087
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004088 std::unique_ptr<DeviceResetEntry> newEntry =
4089 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
4090 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004091 } // release lock
4092
4093 if (needWake) {
4094 mLooper->wake();
4095 }
4096}
4097
Prabir Pradhan7e186182020-11-10 13:56:45 -08004098void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004099 if (DEBUG_INBOUND_EVENT_DETAILS) {
4100 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004101 args->request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004102 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004103
Prabir Pradhan99987712020-11-10 18:43:05 -08004104 bool needWake;
4105 { // acquire lock
4106 std::scoped_lock _l(mLock);
4107 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004108 args->request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004109 needWake = enqueueInboundEventLocked(std::move(entry));
4110 } // release lock
4111
4112 if (needWake) {
4113 mLooper->wake();
4114 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004115}
4116
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004117InputEventInjectionResult InputDispatcher::injectInputEvent(
4118 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4119 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004120 if (DEBUG_INBOUND_EVENT_DETAILS) {
4121 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
4122 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4123 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
4124 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004125 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004126
4127 policyFlags |= POLICY_FLAG_INJECTED;
4128 if (hasInjectionPermission(injectorPid, injectorUid)) {
4129 policyFlags |= POLICY_FLAG_TRUSTED;
4130 }
4131
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004132 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004133 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4134 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4135 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4136 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4137 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004138 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004139 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004140 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004141 }
4142
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004143 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004144 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004145 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004146 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4147 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004148 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004149 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004150 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004151
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004152 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004153 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4154 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4155 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004156 int32_t keyCode = incomingKey.getKeyCode();
4157 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004158 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004159 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004160 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004161 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004162 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4163 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4164 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004165
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004166 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4167 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004168 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004169
4170 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4171 android::base::Timer t;
4172 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4173 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4174 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4175 std::to_string(t.duration().count()).c_str());
4176 }
4177 }
4178
4179 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004180 std::unique_ptr<KeyEntry> injectedEntry =
4181 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004182 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004183 incomingKey.getDisplayId(), policyFlags, action,
4184 flags, keyCode, incomingKey.getScanCode(), metaState,
4185 incomingKey.getRepeatCount(),
4186 incomingKey.getDownTime());
4187 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004188 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004189 }
4190
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004191 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004192 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
4193 int32_t action = motionEvent.getAction();
4194 size_t pointerCount = motionEvent.getPointerCount();
4195 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
4196 int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004197 int32_t flags = motionEvent.getFlags();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004198 int32_t displayId = motionEvent.getDisplayId();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004199 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004200 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004201 }
4202
4203 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004204 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004205 android::base::Timer t;
4206 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4207 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4208 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4209 std::to_string(t.duration().count()).c_str());
4210 }
4211 }
4212
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004213 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4214 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4215 }
4216
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004217 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004218 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4219 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004220 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004221 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4222 resolvedDeviceId, motionEvent.getSource(),
4223 motionEvent.getDisplayId(), policyFlags, action,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004224 actionButton, flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004225 motionEvent.getButtonState(),
4226 motionEvent.getClassification(),
4227 motionEvent.getEdgeFlags(),
4228 motionEvent.getXPrecision(),
4229 motionEvent.getYPrecision(),
4230 motionEvent.getRawXCursorPosition(),
4231 motionEvent.getRawYCursorPosition(),
4232 motionEvent.getDownTime(), uint32_t(pointerCount),
4233 pointerProperties, samplePointerCoords,
4234 motionEvent.getXOffset(),
4235 motionEvent.getYOffset());
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004236 transformMotionEntryForInjectionLocked(*injectedEntry);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004237 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004238 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004239 sampleEventTimes += 1;
4240 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004241 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004242 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4243 resolvedDeviceId, motionEvent.getSource(),
4244 motionEvent.getDisplayId(), policyFlags,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004245 action, actionButton, flags,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004246 motionEvent.getMetaState(),
4247 motionEvent.getButtonState(),
4248 motionEvent.getClassification(),
4249 motionEvent.getEdgeFlags(),
4250 motionEvent.getXPrecision(),
4251 motionEvent.getYPrecision(),
4252 motionEvent.getRawXCursorPosition(),
4253 motionEvent.getRawYCursorPosition(),
4254 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004255 uint32_t(pointerCount), pointerProperties,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004256 samplePointerCoords, motionEvent.getXOffset(),
4257 motionEvent.getYOffset());
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004258 transformMotionEntryForInjectionLocked(*nextInjectedEntry);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004259 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004260 }
4261 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004262 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004263
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004264 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004265 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004266 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004267 }
4268
4269 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004270 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004271 injectionState->injectionIsAsync = true;
4272 }
4273
4274 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004275 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004276
4277 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004278 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004279 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004280 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004281 }
4282
4283 mLock.unlock();
4284
4285 if (needWake) {
4286 mLooper->wake();
4287 }
4288
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004289 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004290 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004291 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004292
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004293 if (syncMode == InputEventInjectionSync::NONE) {
4294 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004295 } else {
4296 for (;;) {
4297 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004298 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004299 break;
4300 }
4301
4302 nsecs_t remainingTimeout = endTime - now();
4303 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004304 if (DEBUG_INJECTION) {
4305 ALOGD("injectInputEvent - Timed out waiting for injection result "
4306 "to become available.");
4307 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004308 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004309 break;
4310 }
4311
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004312 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004313 }
4314
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004315 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4316 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004317 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004318 if (DEBUG_INJECTION) {
4319 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4320 injectionState->pendingForegroundDispatches);
4321 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004322 nsecs_t remainingTimeout = endTime - now();
4323 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004324 if (DEBUG_INJECTION) {
4325 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4326 "dispatches to finish.");
4327 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004328 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004329 break;
4330 }
4331
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004332 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004333 }
4334 }
4335 }
4336
4337 injectionState->release();
4338 } // release lock
4339
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004340 if (DEBUG_INJECTION) {
4341 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
4342 injectionResult, injectorPid, injectorUid);
4343 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004344
4345 return injectionResult;
4346}
4347
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004348std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004349 std::array<uint8_t, 32> calculatedHmac;
4350 std::unique_ptr<VerifiedInputEvent> result;
4351 switch (event.getType()) {
4352 case AINPUT_EVENT_TYPE_KEY: {
4353 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4354 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4355 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004356 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004357 break;
4358 }
4359 case AINPUT_EVENT_TYPE_MOTION: {
4360 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4361 VerifiedMotionEvent verifiedMotionEvent =
4362 verifiedMotionEventFromMotionEvent(motionEvent);
4363 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004364 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004365 break;
4366 }
4367 default: {
4368 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4369 return nullptr;
4370 }
4371 }
4372 if (calculatedHmac == INVALID_HMAC) {
4373 return nullptr;
4374 }
4375 if (calculatedHmac != event.getHmac()) {
4376 return nullptr;
4377 }
4378 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004379}
4380
Michael Wrightd02c5b62014-02-10 15:10:22 -08004381bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004382 return injectorUid == 0 ||
4383 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004384}
4385
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004386void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004387 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004388 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004389 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004390 if (DEBUG_INJECTION) {
4391 ALOGD("Setting input event injection result to %d. "
4392 "injectorPid=%d, injectorUid=%d",
4393 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
4394 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004395
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004396 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004397 // Log the outcome since the injector did not wait for the injection result.
4398 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004399 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004400 ALOGV("Asynchronous input event injection succeeded.");
4401 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004402 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004403 ALOGW("Asynchronous input event injection failed.");
4404 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004405 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004406 ALOGW("Asynchronous input event injection permission denied.");
4407 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004408 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004409 ALOGW("Asynchronous input event injection timed out.");
4410 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004411 case InputEventInjectionResult::PENDING:
4412 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4413 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004414 }
4415 }
4416
4417 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004418 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004419 }
4420}
4421
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004422void InputDispatcher::transformMotionEntryForInjectionLocked(MotionEntry& entry) const {
4423 const bool isRelativeMouseEvent = isFromSource(entry.source, AINPUT_SOURCE_MOUSE_RELATIVE);
4424 if (!isRelativeMouseEvent && !isFromSource(entry.source, AINPUT_SOURCE_CLASS_POINTER)) {
4425 return;
4426 }
4427
4428 // Input injection works in the logical display coordinate space, but the input pipeline works
4429 // display space, so we need to transform the injected events accordingly.
4430 const auto it = mDisplayInfos.find(entry.displayId);
4431 if (it == mDisplayInfos.end()) return;
4432 const auto& transformToDisplay = it->second.transform.inverse();
4433
4434 for (uint32_t i = 0; i < entry.pointerCount; i++) {
4435 PointerCoords& pc = entry.pointerCoords[i];
4436 const auto xy = isRelativeMouseEvent
4437 ? transformWithoutTranslation(transformToDisplay, pc.getX(), pc.getY())
4438 : transformToDisplay.transform(pc.getXYValue());
4439 pc.setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
4440 pc.setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
4441
4442 // Axes with relative values never represent points on a screen, so they should never have
4443 // translation applied. If a device does not report relative values, these values are always
4444 // 0, and will remain unaffected by the following operation.
4445 const auto rel =
4446 transformWithoutTranslation(transformToDisplay,
4447 pc.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
4448 pc.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
4449 pc.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, rel.x);
4450 pc.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, rel.y);
4451 }
4452}
4453
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004454void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4455 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004456 if (injectionState) {
4457 injectionState->pendingForegroundDispatches += 1;
4458 }
4459}
4460
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004461void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4462 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004463 if (injectionState) {
4464 injectionState->pendingForegroundDispatches -= 1;
4465
4466 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004467 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004468 }
4469 }
4470}
4471
chaviw98318de2021-05-19 16:45:23 -05004472const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004473 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004474 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004475 auto it = mWindowHandlesByDisplay.find(displayId);
4476 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004477}
4478
chaviw98318de2021-05-19 16:45:23 -05004479sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004480 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004481 if (windowHandleToken == nullptr) {
4482 return nullptr;
4483 }
4484
Arthur Hungb92218b2018-08-14 12:00:21 +08004485 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004486 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4487 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004488 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004489 return windowHandle;
4490 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004491 }
4492 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004493 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004494}
4495
chaviw98318de2021-05-19 16:45:23 -05004496sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4497 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004498 if (windowHandleToken == nullptr) {
4499 return nullptr;
4500 }
4501
chaviw98318de2021-05-19 16:45:23 -05004502 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004503 if (windowHandle->getToken() == windowHandleToken) {
4504 return windowHandle;
4505 }
4506 }
4507 return nullptr;
4508}
4509
chaviw98318de2021-05-19 16:45:23 -05004510sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4511 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004512 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004513 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4514 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004515 if (handle->getId() == windowHandle->getId() &&
4516 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004517 if (windowHandle->getInfo()->displayId != it.first) {
4518 ALOGE("Found window %s in display %" PRId32
4519 ", but it should belong to display %" PRId32,
4520 windowHandle->getName().c_str(), it.first,
4521 windowHandle->getInfo()->displayId);
4522 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004523 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004524 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004525 }
4526 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004527 return nullptr;
4528}
4529
chaviw98318de2021-05-19 16:45:23 -05004530sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004531 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4532 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004533}
4534
chaviw98318de2021-05-19 16:45:23 -05004535bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004536 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4537 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004538 windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004539 if (connection != nullptr && noInputChannel) {
4540 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4541 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4542 return false;
4543 }
4544
4545 if (connection == nullptr) {
4546 if (!noInputChannel) {
4547 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4548 }
4549 return false;
4550 }
4551 if (!connection->responsive) {
4552 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4553 return false;
4554 }
4555 return true;
4556}
4557
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004558std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4559 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004560 auto connectionIt = mConnectionsByToken.find(token);
4561 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004562 return nullptr;
4563 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004564 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004565}
4566
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004567void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004568 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4569 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004570 // Remove all handles on a display if there are no windows left.
4571 mWindowHandlesByDisplay.erase(displayId);
4572 return;
4573 }
4574
4575 // Since we compare the pointer of input window handles across window updates, we need
4576 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004577 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4578 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4579 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004580 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004581 }
4582
chaviw98318de2021-05-19 16:45:23 -05004583 std::vector<sp<WindowInfoHandle>> newHandles;
4584 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05004585 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004586 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004587 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004588 info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
4589 const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
4590 !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004591 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004592 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004593 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004594 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004595 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004596 }
4597
4598 if (info->displayId != displayId) {
4599 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4600 handle->getName().c_str(), displayId, info->displayId);
4601 continue;
4602 }
4603
Robert Carredd13602020-04-13 17:24:34 -07004604 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4605 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004606 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004607 oldHandle->updateFrom(handle);
4608 newHandles.push_back(oldHandle);
4609 } else {
4610 newHandles.push_back(handle);
4611 }
4612 }
4613
4614 // Insert or replace
4615 mWindowHandlesByDisplay[displayId] = newHandles;
4616}
4617
Arthur Hung72d8dc32020-03-28 00:48:39 +00004618void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004619 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07004620 // TODO(b/198444055): Remove setInputWindows from InputDispatcher.
Arthur Hung72d8dc32020-03-28 00:48:39 +00004621 { // acquire lock
4622 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004623 for (const auto& [displayId, handles] : handlesPerDisplay) {
4624 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004625 }
4626 }
4627 // Wake up poll loop since it may need to make new input dispatching choices.
4628 mLooper->wake();
4629}
4630
Arthur Hungb92218b2018-08-14 12:00:21 +08004631/**
4632 * Called from InputManagerService, update window handle list by displayId that can receive input.
4633 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4634 * If set an empty list, remove all handles from the specific display.
4635 * For focused handle, check if need to change and send a cancel event to previous one.
4636 * For removed handle, check if need to send a cancel event if already in touch.
4637 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004638void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004639 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004640 if (DEBUG_FOCUS) {
4641 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004642 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004643 windowList += iwh->getName() + " ";
4644 }
4645 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4646 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004647
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004648 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
chaviw98318de2021-05-19 16:45:23 -05004649 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004650 const bool noInputWindow =
chaviw98318de2021-05-19 16:45:23 -05004651 window->getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004652 if (noInputWindow && window->getToken() != nullptr) {
4653 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4654 window->getName().c_str());
4655 window->releaseChannel();
4656 }
4657 }
4658
Arthur Hung72d8dc32020-03-28 00:48:39 +00004659 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004660 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004661
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004662 // Save the old windows' orientation by ID before it gets updated.
4663 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004664 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004665 oldWindowOrientations.emplace(handle->getId(),
4666 handle->getInfo()->transform.getOrientation());
4667 }
4668
chaviw98318de2021-05-19 16:45:23 -05004669 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004670
chaviw98318de2021-05-19 16:45:23 -05004671 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004672 if (mLastHoverWindowHandle &&
4673 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4674 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004675 mLastHoverWindowHandle = nullptr;
4676 }
4677
Vishnu Nairc519ff72021-01-21 08:23:08 -08004678 std::optional<FocusResolver::FocusChanges> changes =
4679 mFocusResolver.setInputWindows(displayId, windowHandles);
4680 if (changes) {
4681 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004682 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004683
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004684 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4685 mTouchStatesByDisplay.find(displayId);
4686 if (stateIt != mTouchStatesByDisplay.end()) {
4687 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004688 for (size_t i = 0; i < state.windows.size();) {
4689 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004690 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004691 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004692 ALOGD("Touched window was removed: %s in display %" PRId32,
4693 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004694 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004695 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004696 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4697 if (touchedInputChannel != nullptr) {
4698 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4699 "touched window was removed");
4700 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004701 // Since we are about to drop the touch, cancel the events for the wallpaper as
4702 // well.
4703 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND &&
4704 touchedWindow.windowHandle->getInfo()->hasWallpaper) {
4705 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
4706 if (wallpaper != nullptr) {
4707 sp<Connection> wallpaperConnection =
4708 getConnectionLocked(wallpaper->getToken());
4709 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection,
4710 options);
4711 }
4712 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004713 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004714 state.windows.erase(state.windows.begin() + i);
4715 } else {
4716 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004717 }
4718 }
arthurhungb89ccb02020-12-30 16:19:01 +08004719
arthurhung6d4bed92021-03-17 11:59:33 +08004720 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004721 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004722 if (mDragState &&
4723 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004724 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004725 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004726 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004727 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004728
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004729 if (isPerWindowInputRotationEnabled()) {
4730 // Determine if the orientation of any of the input windows have changed, and cancel all
4731 // pointer events if necessary.
chaviw98318de2021-05-19 16:45:23 -05004732 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4733 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004734 if (newWindowHandle != nullptr &&
4735 newWindowHandle->getInfo()->transform.getOrientation() !=
4736 oldWindowOrientations[oldWindowHandle->getId()]) {
4737 std::shared_ptr<InputChannel> inputChannel =
4738 getInputChannelLocked(newWindowHandle->getToken());
4739 if (inputChannel != nullptr) {
4740 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4741 "touched window's orientation changed");
4742 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4743 }
4744 }
4745 }
4746 }
4747
Arthur Hung72d8dc32020-03-28 00:48:39 +00004748 // Release information for windows that are no longer present.
4749 // This ensures that unused input channels are released promptly.
4750 // Otherwise, they might stick around until the window handle is destroyed
4751 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004752 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004753 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004754 if (DEBUG_FOCUS) {
4755 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004756 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004757 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004758 // To avoid making too many calls into the compat framework, only
4759 // check for window flags when windows are going away.
4760 // TODO(b/157929241) : delete this. This is only needed temporarily
4761 // in order to gather some data about the flag usage
chaviw98318de2021-05-19 16:45:23 -05004762 if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004763 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4764 oldWindowHandle->getName().c_str());
4765 if (mCompatService != nullptr) {
4766 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4767 oldWindowHandle->getInfo()->ownerUid);
4768 }
4769 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004770 }
chaviw291d88a2019-02-14 10:33:58 -08004771 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004772}
4773
4774void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004775 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004776 if (DEBUG_FOCUS) {
4777 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4778 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4779 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004780 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004781 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004782 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004783 } // release lock
4784
4785 // Wake up poll loop since it may need to make new input dispatching choices.
4786 mLooper->wake();
4787}
4788
Vishnu Nair599f1412021-06-21 10:39:58 -07004789void InputDispatcher::setFocusedApplicationLocked(
4790 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4791 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4792 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4793
4794 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4795 return; // This application is already focused. No need to wake up or change anything.
4796 }
4797
4798 // Set the new application handle.
4799 if (inputApplicationHandle != nullptr) {
4800 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4801 } else {
4802 mFocusedApplicationHandlesByDisplay.erase(displayId);
4803 }
4804
4805 // No matter what the old focused application was, stop waiting on it because it is
4806 // no longer focused.
4807 resetNoFocusedWindowTimeoutLocked();
4808}
4809
Tiger Huang721e26f2018-07-24 22:26:19 +08004810/**
4811 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4812 * the display not specified.
4813 *
4814 * We track any unreleased events for each window. If a window loses the ability to receive the
4815 * released event, we will send a cancel event to it. So when the focused display is changed, we
4816 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4817 * display. The display-specified events won't be affected.
4818 */
4819void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004820 if (DEBUG_FOCUS) {
4821 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4822 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004823 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004824 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004825
4826 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004827 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004828 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004829 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004830 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004831 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004832 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004833 CancelationOptions
4834 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4835 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004836 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004837 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4838 }
4839 }
4840 mFocusedDisplayId = displayId;
4841
Chris Ye3c2d6f52020-08-09 10:39:48 -07004842 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004843 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004844 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004845
Vishnu Nairad321cd2020-08-20 16:40:21 -07004846 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004847 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004848 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004849 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004850 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004851 }
4852 }
4853 }
4854
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004855 if (DEBUG_FOCUS) {
4856 logDispatchStateLocked();
4857 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004858 } // release lock
4859
4860 // Wake up poll loop since it may need to make new input dispatching choices.
4861 mLooper->wake();
4862}
4863
Michael Wrightd02c5b62014-02-10 15:10:22 -08004864void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004865 if (DEBUG_FOCUS) {
4866 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4867 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004868
4869 bool changed;
4870 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004871 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004872
4873 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4874 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004875 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004876 }
4877
4878 if (mDispatchEnabled && !enabled) {
4879 resetAndDropEverythingLocked("dispatcher is being disabled");
4880 }
4881
4882 mDispatchEnabled = enabled;
4883 mDispatchFrozen = frozen;
4884 changed = true;
4885 } else {
4886 changed = false;
4887 }
4888
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004889 if (DEBUG_FOCUS) {
4890 logDispatchStateLocked();
4891 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004892 } // release lock
4893
4894 if (changed) {
4895 // Wake up poll loop since it may need to make new input dispatching choices.
4896 mLooper->wake();
4897 }
4898}
4899
4900void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004901 if (DEBUG_FOCUS) {
4902 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4903 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004904
4905 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004906 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004907
4908 if (mInputFilterEnabled == enabled) {
4909 return;
4910 }
4911
4912 mInputFilterEnabled = enabled;
4913 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4914 } // release lock
4915
4916 // Wake up poll loop since there might be work to do to drop everything.
4917 mLooper->wake();
4918}
4919
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004920void InputDispatcher::setInTouchMode(bool inTouchMode) {
4921 std::scoped_lock lock(mLock);
4922 mInTouchMode = inTouchMode;
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004923 // TODO(b/193718270): Fire TouchModeEvent here.
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004924}
4925
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004926void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4927 if (opacity < 0 || opacity > 1) {
4928 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4929 return;
4930 }
4931
4932 std::scoped_lock lock(mLock);
4933 mMaximumObscuringOpacityForTouch = opacity;
4934}
4935
4936void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4937 std::scoped_lock lock(mLock);
4938 mBlockUntrustedTouchesMode = mode;
4939}
4940
Arthur Hungabbb9d82021-09-01 14:52:30 +00004941std::pair<TouchState*, TouchedWindow*> InputDispatcher::findTouchStateAndWindowLocked(
4942 const sp<IBinder>& token) {
4943 for (auto& [displayId, state] : mTouchStatesByDisplay) {
4944 for (TouchedWindow& w : state.windows) {
4945 if (w.windowHandle->getToken() == token) {
4946 return std::make_pair(&state, &w);
4947 }
4948 }
4949 }
4950 return std::make_pair(nullptr, nullptr);
4951}
4952
arthurhungb89ccb02020-12-30 16:19:01 +08004953bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4954 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004955 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004956 if (DEBUG_FOCUS) {
4957 ALOGD("Trivial transfer to same window.");
4958 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004959 return true;
4960 }
4961
Michael Wrightd02c5b62014-02-10 15:10:22 -08004962 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004963 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004964
Arthur Hungabbb9d82021-09-01 14:52:30 +00004965 // Find the target touch state and touched window by fromToken.
4966 auto [state, touchedWindow] = findTouchStateAndWindowLocked(fromToken);
4967 if (state == nullptr || touchedWindow == nullptr) {
4968 ALOGD("Focus transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004969 return false;
4970 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00004971
4972 const int32_t displayId = state->displayId;
4973 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
4974 if (toWindowHandle == nullptr) {
4975 ALOGW("Cannot transfer focus because to window not found.");
4976 return false;
4977 }
4978
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004979 if (DEBUG_FOCUS) {
4980 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00004981 touchedWindow->windowHandle->getName().c_str(),
4982 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004983 }
4984
Arthur Hungabbb9d82021-09-01 14:52:30 +00004985 // Erase old window.
4986 int32_t oldTargetFlags = touchedWindow->targetFlags;
4987 BitSet32 pointerIds = touchedWindow->pointerIds;
4988 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004989
Arthur Hungabbb9d82021-09-01 14:52:30 +00004990 // Add new window.
4991 int32_t newTargetFlags = oldTargetFlags &
4992 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4993 InputTarget::FLAG_DISPATCH_AS_IS);
4994 state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004995
Arthur Hungabbb9d82021-09-01 14:52:30 +00004996 // Store the dragging window.
4997 if (isDragDrop) {
4998 mDragState = std::make_unique<DragState>(toWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004999 }
5000
Arthur Hungabbb9d82021-09-01 14:52:30 +00005001 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005002 sp<Connection> fromConnection = getConnectionLocked(fromToken);
5003 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005004 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005005 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005006 CancelationOptions
5007 options(CancelationOptions::CANCEL_POINTER_EVENTS,
5008 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005009 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08005010 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005011 }
5012
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005013 if (DEBUG_FOCUS) {
5014 logDispatchStateLocked();
5015 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005016 } // release lock
5017
5018 // Wake up poll loop since it may need to make new input dispatching choices.
5019 mLooper->wake();
5020 return true;
5021}
5022
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005023// Binder call
5024bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
5025 sp<IBinder> fromToken;
5026 { // acquire lock
5027 std::scoped_lock _l(mLock);
5028
Arthur Hungabbb9d82021-09-01 14:52:30 +00005029 auto it = std::find_if(mTouchStatesByDisplay.begin(), mTouchStatesByDisplay.end(),
5030 [](const auto& pair) { return pair.second.windows.size() == 1; });
5031 if (it == mTouchStatesByDisplay.end()) {
5032 ALOGW("Cannot transfer touch state because there is no exact window being touched");
5033 return false;
5034 }
5035 const int32_t displayId = it->first;
5036 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005037 if (toWindowHandle == nullptr) {
5038 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
5039 return false;
5040 }
5041
Arthur Hungabbb9d82021-09-01 14:52:30 +00005042 TouchState& state = it->second;
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005043 const TouchedWindow& touchedWindow = state.windows[0];
5044 fromToken = touchedWindow.windowHandle->getToken();
5045 } // release lock
5046
5047 return transferTouchFocus(fromToken, destChannelToken);
5048}
5049
Michael Wrightd02c5b62014-02-10 15:10:22 -08005050void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005051 if (DEBUG_FOCUS) {
5052 ALOGD("Resetting and dropping all events (%s).", reason);
5053 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005054
5055 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
5056 synthesizeCancelationEventsForAllConnectionsLocked(options);
5057
5058 resetKeyRepeatLocked();
5059 releasePendingEventLocked();
5060 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005061 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005062
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005063 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005064 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005065 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07005066 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005067}
5068
5069void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005070 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005071 dumpDispatchStateLocked(dump);
5072
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005073 std::istringstream stream(dump);
5074 std::string line;
5075
5076 while (std::getline(stream, line, '\n')) {
5077 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005078 }
5079}
5080
Prabir Pradhan99987712020-11-10 18:43:05 -08005081std::string InputDispatcher::dumpPointerCaptureStateLocked() {
5082 std::string dump;
5083
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005084 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5085 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005086
5087 std::string windowName = "None";
5088 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005089 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005090 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5091 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5092 : "token has capture without window";
5093 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005094 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005095
5096 return dump;
5097}
5098
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005099void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005100 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5101 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5102 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005103 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005104
Tiger Huang721e26f2018-07-24 22:26:19 +08005105 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5106 dump += StringPrintf(INDENT "FocusedApplications:\n");
5107 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5108 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005109 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005110 const std::chrono::duration timeout =
5111 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005112 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005113 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005114 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005115 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005116 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005117 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005118 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005119
Vishnu Nairc519ff72021-01-21 08:23:08 -08005120 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005121 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005122
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005123 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005124 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005125 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
5126 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005127 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005128 state.displayId, toString(state.down), toString(state.split),
5129 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005130 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005131 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005132 for (size_t i = 0; i < state.windows.size(); i++) {
5133 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005134 dump += StringPrintf(INDENT4
5135 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
5136 i, touchedWindow.windowHandle->getName().c_str(),
5137 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005138 }
5139 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005140 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005141 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005142 }
5143 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005144 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005145 }
5146
arthurhung6d4bed92021-03-17 11:59:33 +08005147 if (mDragState) {
5148 dump += StringPrintf(INDENT "DragState:\n");
5149 mDragState->dump(dump, INDENT2);
5150 }
5151
Arthur Hungb92218b2018-08-14 12:00:21 +08005152 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005153 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5154 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5155 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5156 const auto& displayInfo = it->second;
5157 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5158 displayInfo.logicalHeight);
5159 displayInfo.transform.dump(dump, "transform", INDENT4);
5160 } else {
5161 dump += INDENT2 "No DisplayInfo found!\n";
5162 }
5163
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005164 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005165 dump += INDENT2 "Windows:\n";
5166 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005167 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5168 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005169
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005170 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005171 "paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005172 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005173 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005174 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005175 "applicationInfo.name=%s, "
5176 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005177 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005178 i, windowInfo->name.c_str(), windowInfo->id,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005179 windowInfo->displayId, toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07005180 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005181 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005182 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01005183 windowInfo->flags.string().c_str(),
Dominik Laskowski75788452021-02-09 18:51:25 -08005184 ftl::enum_string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01005185 windowInfo->frameLeft, windowInfo->frameTop,
5186 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005187 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005188 windowInfo->applicationInfo.name.c_str(),
5189 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005190 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01005191 dump += StringPrintf(", inputFeatures=%s",
5192 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005193 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005194 "ms, trustedOverlay=%s, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005195 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005196 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005197 millis(windowInfo->dispatchingTimeout),
5198 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005199 toString(windowInfo->token != nullptr),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005200 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005201 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005202 }
5203 } else {
5204 dump += INDENT2 "Windows: <none>\n";
5205 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005206 }
5207 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005208 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005209 }
5210
Michael Wright3dd60e22019-03-27 22:06:44 +00005211 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005212 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005213 const std::vector<Monitor>& monitors = it.second;
5214 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
5215 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005216 }
5217 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005218 const std::vector<Monitor>& monitors = it.second;
5219 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
5220 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005221 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005222 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00005223 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005224 }
5225
5226 nsecs_t currentTime = now();
5227
5228 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005229 if (!mRecentQueue.empty()) {
5230 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005231 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005232 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005233 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005234 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005235 }
5236 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005237 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005238 }
5239
5240 // Dump event currently being dispatched.
5241 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005242 dump += INDENT "PendingEvent:\n";
5243 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005244 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005245 dump += StringPrintf(", age=%" PRId64 "ms\n",
5246 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005247 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005248 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005249 }
5250
5251 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005252 if (!mInboundQueue.empty()) {
5253 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005254 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005255 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005256 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005257 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005258 }
5259 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005260 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005261 }
5262
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005263 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005264 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005265 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5266 const KeyReplacement& replacement = pair.first;
5267 int32_t newKeyCode = pair.second;
5268 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005269 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005270 }
5271 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005272 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005273 }
5274
Prabir Pradhancef936d2021-07-21 16:17:52 +00005275 if (!mCommandQueue.empty()) {
5276 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5277 } else {
5278 dump += INDENT "CommandQueue: <empty>\n";
5279 }
5280
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005281 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005282 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005283 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005284 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005285 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005286 connection->inputChannel->getFd().get(),
5287 connection->getInputChannelName().c_str(),
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005288 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005289 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005290
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005291 if (!connection->outboundQueue.empty()) {
5292 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5293 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005294 dump += dumpQueue(connection->outboundQueue, currentTime);
5295
Michael Wrightd02c5b62014-02-10 15:10:22 -08005296 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005297 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005298 }
5299
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005300 if (!connection->waitQueue.empty()) {
5301 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5302 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005303 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005304 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005305 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005306 }
5307 }
5308 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005309 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005310 }
5311
5312 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005313 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5314 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005315 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005316 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005317 }
5318
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005319 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005320 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5321 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5322 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005323 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005324 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005325}
5326
Michael Wright3dd60e22019-03-27 22:06:44 +00005327void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5328 const size_t numMonitors = monitors.size();
5329 for (size_t i = 0; i < numMonitors; i++) {
5330 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005331 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005332 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5333 dump += "\n";
5334 }
5335}
5336
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005337class LooperEventCallback : public LooperCallback {
5338public:
5339 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5340 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5341
5342private:
5343 std::function<int(int events)> mCallback;
5344};
5345
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005346Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005347 if (DEBUG_CHANNEL_CREATION) {
5348 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5349 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005350
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005351 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005352 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005353 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005354
5355 if (result) {
5356 return base::Error(result) << "Failed to open input channel pair with name " << name;
5357 }
5358
Michael Wrightd02c5b62014-02-10 15:10:22 -08005359 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005360 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005361 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005362 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005363 sp<Connection> connection =
5364 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005365
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005366 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5367 ALOGE("Created a new connection, but the token %p is already known", token.get());
5368 }
5369 mConnectionsByToken.emplace(token, connection);
5370
5371 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5372 this, std::placeholders::_1, token);
5373
5374 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005375 } // release lock
5376
5377 // Wake the looper because some connections have changed.
5378 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005379 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005380}
5381
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005382Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5383 bool isGestureMonitor,
5384 const std::string& name,
5385 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005386 std::shared_ptr<InputChannel> serverChannel;
5387 std::unique_ptr<InputChannel> clientChannel;
5388 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5389 if (result) {
5390 return base::Error(result) << "Failed to open input channel pair with name " << name;
5391 }
5392
Michael Wright3dd60e22019-03-27 22:06:44 +00005393 { // acquire lock
5394 std::scoped_lock _l(mLock);
5395
5396 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005397 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5398 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005399 }
5400
Garfield Tan15601662020-09-22 15:32:38 -07005401 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005402 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005403 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005404
5405 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5406 ALOGE("Created a new connection, but the token %p is already known", token.get());
5407 }
5408 mConnectionsByToken.emplace(token, connection);
5409 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5410 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005411
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005412 auto& monitorsByDisplay =
5413 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005414 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005415
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005416 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Siarhei Vishniakouc961c742021-05-19 19:16:59 +00005417 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5418 displayId, toString(isGestureMonitor), pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005419 }
Garfield Tan15601662020-09-22 15:32:38 -07005420
Michael Wright3dd60e22019-03-27 22:06:44 +00005421 // Wake the looper because some connections have changed.
5422 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005423 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005424}
5425
Garfield Tan15601662020-09-22 15:32:38 -07005426status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005427 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005428 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005429
Garfield Tan15601662020-09-22 15:32:38 -07005430 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005431 if (status) {
5432 return status;
5433 }
5434 } // release lock
5435
5436 // Wake the poll loop because removing the connection may have changed the current
5437 // synchronization state.
5438 mLooper->wake();
5439 return OK;
5440}
5441
Garfield Tan15601662020-09-22 15:32:38 -07005442status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5443 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005444 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005445 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005446 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005447 return BAD_VALUE;
5448 }
5449
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005450 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005451
Michael Wrightd02c5b62014-02-10 15:10:22 -08005452 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005453 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005454 }
5455
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005456 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005457
5458 nsecs_t currentTime = now();
5459 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5460
5461 connection->status = Connection::STATUS_ZOMBIE;
5462 return OK;
5463}
5464
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005465void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5466 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5467 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005468}
5469
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005470void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005471 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005472 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005473 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005474 std::vector<Monitor>& monitors = it->second;
5475 const size_t numMonitors = monitors.size();
5476 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005477 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005478 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5479 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005480 monitors.erase(monitors.begin() + i);
5481 break;
5482 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005483 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005484 if (monitors.empty()) {
5485 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005486 } else {
5487 ++it;
5488 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005489 }
5490}
5491
Michael Wright3dd60e22019-03-27 22:06:44 +00005492status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5493 { // acquire lock
5494 std::scoped_lock _l(mLock);
5495 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5496
5497 if (!foundDisplayId) {
5498 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5499 return BAD_VALUE;
5500 }
5501 int32_t displayId = foundDisplayId.value();
5502
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005503 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5504 mTouchStatesByDisplay.find(displayId);
5505 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005506 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5507 return BAD_VALUE;
5508 }
5509
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005510 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005511 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005512 std::optional<int32_t> foundDeviceId;
Prabir Pradhan0a99c922021-09-03 08:27:53 -07005513 for (const auto& monitor : state.gestureMonitors) {
5514 if (monitor.inputChannel->getConnectionToken() == token) {
5515 requestingChannel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005516 foundDeviceId = state.deviceId;
5517 }
5518 }
5519 if (!foundDeviceId || !state.down) {
5520 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005521 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005522 return BAD_VALUE;
5523 }
5524 int32_t deviceId = foundDeviceId.value();
5525
5526 // Send cancel events to all the input channels we're stealing from.
5527 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005528 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005529 options.deviceId = deviceId;
5530 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005531 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005532 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005533 std::shared_ptr<InputChannel> channel =
5534 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005535 if (channel != nullptr) {
5536 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005537 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005538 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005539 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005540 canceledWindows += "]";
5541 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5542 canceledWindows.c_str());
5543
Michael Wright3dd60e22019-03-27 22:06:44 +00005544 // Then clear the current touch state so we stop dispatching to them as well.
5545 state.filterNonMonitors();
5546 }
5547 return OK;
5548}
5549
Prabir Pradhan99987712020-11-10 18:43:05 -08005550void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5551 { // acquire lock
5552 std::scoped_lock _l(mLock);
5553 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005554 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005555 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5556 windowHandle != nullptr ? windowHandle->getName().c_str()
5557 : "token without window");
5558 }
5559
Vishnu Nairc519ff72021-01-21 08:23:08 -08005560 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005561 if (focusedToken != windowToken) {
5562 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5563 enabled ? "enable" : "disable");
5564 return;
5565 }
5566
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005567 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08005568 ALOGW("Ignoring request to %s Pointer Capture: "
5569 "window has %s requested pointer capture.",
5570 enabled ? "enable" : "disable", enabled ? "already" : "not");
5571 return;
5572 }
5573
Prabir Pradhan99987712020-11-10 18:43:05 -08005574 setPointerCaptureLocked(enabled);
5575 } // release lock
5576
5577 // Wake the thread to process command entries.
5578 mLooper->wake();
5579}
5580
Michael Wright3dd60e22019-03-27 22:06:44 +00005581std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5582 const sp<IBinder>& token) {
5583 for (const auto& it : mGestureMonitorsByDisplay) {
5584 const std::vector<Monitor>& monitors = it.second;
5585 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005586 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005587 return it.first;
5588 }
5589 }
5590 }
5591 return std::nullopt;
5592}
5593
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005594std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5595 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5596 if (gesturePid.has_value()) {
5597 return gesturePid;
5598 }
5599 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5600}
5601
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005602sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005603 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005604 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005605 }
5606
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005607 for (const auto& [token, connection] : mConnectionsByToken) {
5608 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005609 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005610 }
5611 }
Robert Carr4e670e52018-08-15 13:26:12 -07005612
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005613 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005614}
5615
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005616std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5617 sp<Connection> connection = getConnectionLocked(connectionToken);
5618 if (connection == nullptr) {
5619 return "<nullptr>";
5620 }
5621 return connection->getInputChannelName();
5622}
5623
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005624void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005625 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005626 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005627}
5628
Prabir Pradhancef936d2021-07-21 16:17:52 +00005629void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5630 const sp<Connection>& connection, uint32_t seq,
5631 bool handled, nsecs_t consumeTime) {
5632 // Handle post-event policy actions.
5633 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5634 if (dispatchEntryIt == connection->waitQueue.end()) {
5635 return;
5636 }
5637 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5638 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5639 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5640 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5641 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5642 }
5643 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5644 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5645 connection->inputChannel->getConnectionToken(),
5646 dispatchEntry->deliveryTime, consumeTime, finishTime);
5647 }
5648
5649 bool restartEvent;
5650 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5651 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5652 restartEvent =
5653 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5654 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5655 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5656 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5657 handled);
5658 } else {
5659 restartEvent = false;
5660 }
5661
5662 // Dequeue the event and start the next cycle.
5663 // Because the lock might have been released, it is possible that the
5664 // contents of the wait queue to have been drained, so we need to double-check
5665 // a few things.
5666 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5667 if (dispatchEntryIt != connection->waitQueue.end()) {
5668 dispatchEntry = *dispatchEntryIt;
5669 connection->waitQueue.erase(dispatchEntryIt);
5670 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5671 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5672 if (!connection->responsive) {
5673 connection->responsive = isConnectionResponsive(*connection);
5674 if (connection->responsive) {
5675 // The connection was unresponsive, and now it's responsive.
5676 processConnectionResponsiveLocked(*connection);
5677 }
5678 }
5679 traceWaitQueueLength(*connection);
5680 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
5681 connection->outboundQueue.push_front(dispatchEntry);
5682 traceOutboundQueueLength(*connection);
5683 } else {
5684 releaseDispatchEntry(dispatchEntry);
5685 }
5686 }
5687
5688 // Start the next dispatch cycle for this connection.
5689 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005690}
5691
Prabir Pradhancef936d2021-07-21 16:17:52 +00005692void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5693 const sp<IBinder>& newToken) {
5694 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5695 scoped_unlock unlock(mLock);
5696 mPolicy->notifyFocusChanged(oldToken, newToken);
5697 };
5698 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005699}
5700
Prabir Pradhancef936d2021-07-21 16:17:52 +00005701void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5702 auto command = [this, token, x, y]() REQUIRES(mLock) {
5703 scoped_unlock unlock(mLock);
5704 mPolicy->notifyDropWindow(token, x, y);
5705 };
5706 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005707}
5708
Prabir Pradhancef936d2021-07-21 16:17:52 +00005709void InputDispatcher::sendUntrustedTouchCommandLocked(const std::string& obscuringPackage) {
5710 auto command = [this, obscuringPackage]() REQUIRES(mLock) {
5711 scoped_unlock unlock(mLock);
5712 mPolicy->notifyUntrustedTouch(obscuringPackage);
5713 };
5714 postCommandLocked(std::move(command));
arthurhungf452d0b2021-01-06 00:19:52 +08005715}
5716
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005717void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5718 if (connection == nullptr) {
5719 LOG_ALWAYS_FATAL("Caller must check for nullness");
5720 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005721 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5722 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005723 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005724 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005725 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005726 return;
5727 }
5728 /**
5729 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5730 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5731 * has changed. This could cause newer entries to time out before the already dispatched
5732 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5733 * processes the events linearly. So providing information about the oldest entry seems to be
5734 * most useful.
5735 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005736 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005737 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5738 std::string reason =
5739 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005740 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005741 ns2ms(currentWait),
5742 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005743 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005744 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005745
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005746 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5747
5748 // Stop waking up for events on this connection, it is already unresponsive
5749 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005750}
5751
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005752void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5753 std::string reason =
5754 StringPrintf("%s does not have a focused window", application->getName().c_str());
5755 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005756
Prabir Pradhancef936d2021-07-21 16:17:52 +00005757 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5758 scoped_unlock unlock(mLock);
5759 mPolicy->notifyNoFocusedWindowAnr(application);
5760 };
5761 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005762}
5763
chaviw98318de2021-05-19 16:45:23 -05005764void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005765 const std::string& reason) {
5766 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5767 updateLastAnrStateLocked(windowLabel, reason);
5768}
5769
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005770void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5771 const std::string& reason) {
5772 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005773 updateLastAnrStateLocked(windowLabel, reason);
5774}
5775
5776void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5777 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005778 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005779 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005780 struct tm tm;
5781 localtime_r(&t, &tm);
5782 char timestr[64];
5783 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005784 mLastAnrState.clear();
5785 mLastAnrState += INDENT "ANR:\n";
5786 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005787 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5788 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005789 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005790}
5791
Prabir Pradhancef936d2021-07-21 16:17:52 +00005792void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5793 KeyEntry& entry) {
5794 const KeyEvent event = createKeyEvent(entry);
5795 nsecs_t delay = 0;
5796 { // release lock
5797 scoped_unlock unlock(mLock);
5798 android::base::Timer t;
5799 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5800 entry.policyFlags);
5801 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5802 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5803 std::to_string(t.duration().count()).c_str());
5804 }
5805 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005806
5807 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005808 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005809 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005810 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005811 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005812 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5813 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005814 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005815}
5816
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005817void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005818 auto command = [this, pid, reason = std::move(reason)]() REQUIRES(mLock) {
5819 scoped_unlock unlock(mLock);
5820 mPolicy->notifyMonitorUnresponsive(pid, reason);
5821 };
5822 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005823}
5824
Prabir Pradhancef936d2021-07-21 16:17:52 +00005825void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005826 std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005827 auto command = [this, token, reason = std::move(reason)]() REQUIRES(mLock) {
5828 scoped_unlock unlock(mLock);
5829 mPolicy->notifyWindowUnresponsive(token, reason);
5830 };
5831 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005832}
5833
5834void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005835 auto command = [this, pid]() REQUIRES(mLock) {
5836 scoped_unlock unlock(mLock);
5837 mPolicy->notifyMonitorResponsive(pid);
5838 };
5839 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005840}
5841
Prabir Pradhancef936d2021-07-21 16:17:52 +00005842void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) {
5843 auto command = [this, connectionToken]() REQUIRES(mLock) {
5844 scoped_unlock unlock(mLock);
5845 mPolicy->notifyWindowResponsive(connectionToken);
5846 };
5847 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005848}
5849
5850/**
5851 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5852 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5853 * command entry to the command queue.
5854 */
5855void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5856 std::string reason) {
5857 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5858 if (connection.monitor) {
5859 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5860 reason.c_str());
5861 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5862 if (!pid.has_value()) {
5863 ALOGE("Could not find unresponsive monitor for connection %s",
5864 connection.inputChannel->getName().c_str());
5865 return;
5866 }
5867 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5868 return;
5869 }
5870 // If not a monitor, must be a window
5871 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5872 reason.c_str());
5873 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5874}
5875
5876/**
5877 * Tell the policy that a connection has become responsive so that it can stop ANR.
5878 */
5879void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5880 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5881 if (connection.monitor) {
5882 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5883 if (!pid.has_value()) {
5884 ALOGE("Could not find responsive monitor for connection %s",
5885 connection.inputChannel->getName().c_str());
5886 return;
5887 }
5888 sendMonitorResponsiveCommandLocked(pid.value());
5889 return;
5890 }
5891 // If not a monitor, must be a window
5892 sendWindowResponsiveCommandLocked(connectionToken);
5893}
5894
Prabir Pradhancef936d2021-07-21 16:17:52 +00005895bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005896 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005897 KeyEntry& keyEntry, bool handled) {
5898 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005899 if (!handled) {
5900 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005901 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005902 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005903 return false;
5904 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005905
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005906 // Get the fallback key state.
5907 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005908 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005909 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005910 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005911 connection->inputState.removeFallbackKey(originalKeyCode);
5912 }
5913
5914 if (handled || !dispatchEntry->hasForegroundTarget()) {
5915 // If the application handles the original key for which we previously
5916 // generated a fallback or if the window is not a foreground window,
5917 // then cancel the associated fallback key, if any.
5918 if (fallbackKeyCode != -1) {
5919 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005920 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5921 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
5922 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5923 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
5924 keyEntry.policyFlags);
5925 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005926 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005927 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005928
5929 mLock.unlock();
5930
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005931 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005932 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005933
5934 mLock.lock();
5935
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005936 // Cancel the fallback key.
5937 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005938 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005939 "application handled the original non-fallback key "
5940 "or is no longer a foreground target, "
5941 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005942 options.keyCode = fallbackKeyCode;
5943 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005944 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005945 connection->inputState.removeFallbackKey(originalKeyCode);
5946 }
5947 } else {
5948 // If the application did not handle a non-fallback key, first check
5949 // that we are in a good state to perform unhandled key event processing
5950 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005951 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005952 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005953 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5954 ALOGD("Unhandled key event: Skipping unhandled key event processing "
5955 "since this is not an initial down. "
5956 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5957 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5958 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005959 return false;
5960 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005961
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005962 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005963 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5964 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
5965 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5966 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5967 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005968 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005969
5970 mLock.unlock();
5971
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005972 bool fallback =
5973 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005974 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005975
5976 mLock.lock();
5977
5978 if (connection->status != Connection::STATUS_NORMAL) {
5979 connection->inputState.removeFallbackKey(originalKeyCode);
5980 return false;
5981 }
5982
5983 // Latch the fallback keycode for this key on an initial down.
5984 // The fallback keycode cannot change at any other point in the lifecycle.
5985 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005986 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005987 fallbackKeyCode = event.getKeyCode();
5988 } else {
5989 fallbackKeyCode = AKEYCODE_UNKNOWN;
5990 }
5991 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5992 }
5993
5994 ALOG_ASSERT(fallbackKeyCode != -1);
5995
5996 // Cancel the fallback key if the policy decides not to send it anymore.
5997 // We will continue to dispatch the key to the policy but we will no
5998 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005999 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
6000 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006001 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6002 if (fallback) {
6003 ALOGD("Unhandled key event: Policy requested to send key %d"
6004 "as a fallback for %d, but on the DOWN it had requested "
6005 "to send %d instead. Fallback canceled.",
6006 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
6007 } else {
6008 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6009 "but on the DOWN it had requested to send %d. "
6010 "Fallback canceled.",
6011 originalKeyCode, fallbackKeyCode);
6012 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006013 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006014
6015 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
6016 "canceling fallback, policy no longer desires it");
6017 options.keyCode = fallbackKeyCode;
6018 synthesizeCancelationEventsForConnectionLocked(connection, options);
6019
6020 fallback = false;
6021 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006022 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006023 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006024 }
6025 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006026
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006027 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6028 {
6029 std::string msg;
6030 const KeyedVector<int32_t, int32_t>& fallbackKeys =
6031 connection->inputState.getFallbackKeys();
6032 for (size_t i = 0; i < fallbackKeys.size(); i++) {
6033 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
6034 }
6035 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6036 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006037 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006038 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006039
6040 if (fallback) {
6041 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006042 keyEntry.eventTime = event.getEventTime();
6043 keyEntry.deviceId = event.getDeviceId();
6044 keyEntry.source = event.getSource();
6045 keyEntry.displayId = event.getDisplayId();
6046 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
6047 keyEntry.keyCode = fallbackKeyCode;
6048 keyEntry.scanCode = event.getScanCode();
6049 keyEntry.metaState = event.getMetaState();
6050 keyEntry.repeatCount = event.getRepeatCount();
6051 keyEntry.downTime = event.getDownTime();
6052 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006053
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006054 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6055 ALOGD("Unhandled key event: Dispatching fallback key. "
6056 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
6057 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
6058 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006059 return true; // restart the event
6060 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006061 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6062 ALOGD("Unhandled key event: No fallback key.");
6063 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006064
6065 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006066 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006067 }
6068 }
6069 return false;
6070}
6071
Prabir Pradhancef936d2021-07-21 16:17:52 +00006072bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006073 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006074 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006075 return false;
6076}
6077
Michael Wrightd02c5b62014-02-10 15:10:22 -08006078void InputDispatcher::traceInboundQueueLengthLocked() {
6079 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006080 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006081 }
6082}
6083
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006084void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006085 if (ATRACE_ENABLED()) {
6086 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006087 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6088 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006089 }
6090}
6091
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006092void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006093 if (ATRACE_ENABLED()) {
6094 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006095 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6096 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006097 }
6098}
6099
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006100void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006101 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006102
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006103 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006104 dumpDispatchStateLocked(dump);
6105
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006106 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006107 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006108 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006109 }
6110}
6111
6112void InputDispatcher::monitor() {
6113 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006114 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006115 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006116 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006117}
6118
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006119/**
6120 * Wake up the dispatcher and wait until it processes all events and commands.
6121 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6122 * this method can be safely called from any thread, as long as you've ensured that
6123 * the work you are interested in completing has already been queued.
6124 */
6125bool InputDispatcher::waitForIdle() {
6126 /**
6127 * Timeout should represent the longest possible time that a device might spend processing
6128 * events and commands.
6129 */
6130 constexpr std::chrono::duration TIMEOUT = 100ms;
6131 std::unique_lock lock(mLock);
6132 mLooper->wake();
6133 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6134 return result == std::cv_status::no_timeout;
6135}
6136
Vishnu Naire798b472020-07-23 13:52:21 -07006137/**
6138 * Sets focus to the window identified by the token. This must be called
6139 * after updating any input window handles.
6140 *
6141 * Params:
6142 * request.token - input channel token used to identify the window that should gain focus.
6143 * request.focusedToken - the token that the caller expects currently to be focused. If the
6144 * specified token does not match the currently focused window, this request will be dropped.
6145 * If the specified focused token matches the currently focused window, the call will succeed.
6146 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6147 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6148 * when requesting the focus change. This determines which request gets
6149 * precedence if there is a focus change request from another source such as pointer down.
6150 */
Vishnu Nair958da932020-08-21 17:12:37 -07006151void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6152 { // acquire lock
6153 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006154 std::optional<FocusResolver::FocusChanges> changes =
6155 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6156 if (changes) {
6157 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006158 }
6159 } // release lock
6160 // Wake up poll loop since it may need to make new input dispatching choices.
6161 mLooper->wake();
6162}
6163
Vishnu Nairc519ff72021-01-21 08:23:08 -08006164void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6165 if (changes.oldFocus) {
6166 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006167 if (focusedInputChannel) {
6168 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6169 "focus left window");
6170 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006171 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006172 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006173 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006174 if (changes.newFocus) {
6175 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006176 }
6177
Prabir Pradhan99987712020-11-10 18:43:05 -08006178 // If a window has pointer capture, then it must have focus. We need to ensure that this
6179 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6180 // If the window loses focus before it loses pointer capture, then the window can be in a state
6181 // where it has pointer capture but not focus, violating the contract. Therefore we must
6182 // dispatch the pointer capture event before the focus event. Since focus events are added to
6183 // the front of the queue (above), we add the pointer capture event to the front of the queue
6184 // after the focus events are added. This ensures the pointer capture event ends up at the
6185 // front.
6186 disablePointerCaptureForcedLocked();
6187
Vishnu Nairc519ff72021-01-21 08:23:08 -08006188 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006189 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006190 }
6191}
Vishnu Nair958da932020-08-21 17:12:37 -07006192
Prabir Pradhan99987712020-11-10 18:43:05 -08006193void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006194 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006195 return;
6196 }
6197
6198 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6199
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006200 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006201 setPointerCaptureLocked(false);
6202 }
6203
6204 if (!mWindowTokenWithPointerCapture) {
6205 // No need to send capture changes because no window has capture.
6206 return;
6207 }
6208
6209 if (mPendingEvent != nullptr) {
6210 // Move the pending event to the front of the queue. This will give the chance
6211 // for the pending event to be dropped if it is a captured event.
6212 mInboundQueue.push_front(mPendingEvent);
6213 mPendingEvent = nullptr;
6214 }
6215
6216 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006217 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006218 mInboundQueue.push_front(std::move(entry));
6219}
6220
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006221void InputDispatcher::setPointerCaptureLocked(bool enable) {
6222 mCurrentPointerCaptureRequest.enable = enable;
6223 mCurrentPointerCaptureRequest.seq++;
6224 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006225 scoped_unlock unlock(mLock);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006226 mPolicy->setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006227 };
6228 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006229}
6230
Vishnu Nair599f1412021-06-21 10:39:58 -07006231void InputDispatcher::displayRemoved(int32_t displayId) {
6232 { // acquire lock
6233 std::scoped_lock _l(mLock);
6234 // Set an empty list to remove all handles from the specific display.
6235 setInputWindowsLocked(/* window handles */ {}, displayId);
6236 setFocusedApplicationLocked(displayId, nullptr);
6237 // Call focus resolver to clean up stale requests. This must be called after input windows
6238 // have been removed for the removed display.
6239 mFocusResolver.displayRemoved(displayId);
6240 } // release lock
6241
6242 // Wake up poll loop since it may need to make new input dispatching choices.
6243 mLooper->wake();
6244}
6245
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006246void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
6247 const std::vector<DisplayInfo>& displayInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006248 // The listener sends the windows as a flattened array. Separate the windows by display for
6249 // more convenient parsing.
6250 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
chaviw15fab6f2021-06-07 14:15:52 -05006251 for (const auto& info : windowInfos) {
6252 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
6253 handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
6254 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006255
6256 { // acquire lock
6257 std::scoped_lock _l(mLock);
6258 mDisplayInfos.clear();
6259 for (const auto& displayInfo : displayInfos) {
6260 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6261 }
6262
6263 for (const auto& [displayId, handles] : handlesPerDisplay) {
6264 setInputWindowsLocked(handles, displayId);
6265 }
6266 }
6267 // Wake up poll loop since it may need to make new input dispatching choices.
6268 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006269}
6270
Vishnu Nair062a8672021-09-03 16:07:44 -07006271bool InputDispatcher::shouldDropInput(
6272 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
6273 if (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT) ||
6274 (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT_IF_OBSCURED) &&
6275 isWindowObscuredLocked(windowHandle))) {
6276 ALOGW("Dropping %s event targeting %s as requested by input feature %s on display "
6277 "%" PRId32 ".",
6278 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
6279 windowHandle->getInfo()->inputFeatures.string().c_str(),
6280 windowHandle->getInfo()->displayId);
6281 return true;
6282 }
6283 return false;
6284}
6285
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006286void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
6287 const std::vector<gui::WindowInfo>& windowInfos,
6288 const std::vector<DisplayInfo>& displayInfos) {
6289 mDispatcher.onWindowInfosChanged(windowInfos, displayInfos);
6290}
6291
Garfield Tane84e6f92019-08-29 17:28:41 -07006292} // namespace android::inputdispatcher