blob: 3db3907f5c658b148ab13580ac023c6c2c96fc9e [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 &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -0700918 isFromSource(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
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001612 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001613
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);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001998 const bool isFromMouse = isFromSource(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()) {
Prabir Pradhanb5402b22021-10-04 05:52:50 -07002544 const auto& displayTransform = it->second.transform;
2545 target.displayTransform = displayTransform;
2546 t = displayTransform;
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002547 }
chaviw1ff3d1e2020-07-01 15:53:47 -07002548 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002549 inputTargets.push_back(target);
2550}
2551
chaviw98318de2021-05-19 16:45:23 -05002552bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002553 const InjectionState* injectionState) {
2554 if (injectionState &&
2555 (windowHandle == nullptr ||
2556 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2557 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002558 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002559 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002560 "owned by uid %d",
2561 injectionState->injectorPid, injectionState->injectorUid,
2562 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002563 } else {
2564 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002565 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002566 }
2567 return false;
2568 }
2569 return true;
2570}
2571
Robert Carrc9bf1d32020-04-13 17:21:08 -07002572/**
2573 * Indicate whether one window handle should be considered as obscuring
2574 * another window handle. We only check a few preconditions. Actually
2575 * checking the bounds is left to the caller.
2576 */
chaviw98318de2021-05-19 16:45:23 -05002577static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2578 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002579 // Compare by token so cloned layers aren't counted
2580 if (haveSameToken(windowHandle, otherHandle)) {
2581 return false;
2582 }
2583 auto info = windowHandle->getInfo();
2584 auto otherInfo = otherHandle->getInfo();
2585 if (!otherInfo->visible) {
2586 return false;
chaviw98318de2021-05-19 16:45:23 -05002587 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002588 // Those act as if they were invisible, so we don't need to flag them.
2589 // We do want to potentially flag touchable windows even if they have 0
2590 // opacity, since they can consume touches and alter the effects of the
2591 // user interaction (eg. apps that rely on
2592 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2593 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2594 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002595 } else if (info->ownerUid == otherInfo->ownerUid) {
2596 // If ownerUid is the same we don't generate occlusion events as there
2597 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002598 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002599 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002600 return false;
2601 } else if (otherInfo->displayId != info->displayId) {
2602 return false;
2603 }
2604 return true;
2605}
2606
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002607/**
2608 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2609 * untrusted, one should check:
2610 *
2611 * 1. If result.hasBlockingOcclusion is true.
2612 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2613 * BLOCK_UNTRUSTED.
2614 *
2615 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2616 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2617 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2618 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2619 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2620 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2621 *
2622 * If neither of those is true, then it means the touch can be allowed.
2623 */
2624InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002625 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2626 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002627 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002628 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002629 TouchOcclusionInfo info;
2630 info.hasBlockingOcclusion = false;
2631 info.obscuringOpacity = 0;
2632 info.obscuringUid = -1;
2633 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002634 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002635 if (windowHandle == otherHandle) {
2636 break; // All future windows are below us. Exit early.
2637 }
chaviw98318de2021-05-19 16:45:23 -05002638 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002639 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2640 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002641 if (DEBUG_TOUCH_OCCLUSION) {
2642 info.debugInfo.push_back(
2643 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2644 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002645 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2646 // we perform the checks below to see if the touch can be propagated or not based on the
2647 // window's touch occlusion mode
2648 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2649 info.hasBlockingOcclusion = true;
2650 info.obscuringUid = otherInfo->ownerUid;
2651 info.obscuringPackage = otherInfo->packageName;
2652 break;
2653 }
2654 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2655 uint32_t uid = otherInfo->ownerUid;
2656 float opacity =
2657 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2658 // Given windows A and B:
2659 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2660 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2661 opacityByUid[uid] = opacity;
2662 if (opacity > info.obscuringOpacity) {
2663 info.obscuringOpacity = opacity;
2664 info.obscuringUid = uid;
2665 info.obscuringPackage = otherInfo->packageName;
2666 }
2667 }
2668 }
2669 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002670 if (DEBUG_TOUCH_OCCLUSION) {
2671 info.debugInfo.push_back(
2672 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2673 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002674 return info;
2675}
2676
chaviw98318de2021-05-19 16:45:23 -05002677std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002678 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002679 return StringPrintf(INDENT2
2680 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2681 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2682 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2683 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Dominik Laskowski75788452021-02-09 18:51:25 -08002684 isTouchedWindow ? "[TOUCHED] " : "", ftl::enum_string(info->type).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002685 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002686 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2687 info->frameTop, info->frameRight, info->frameBottom,
2688 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002689 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2690 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2691 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002692}
2693
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002694bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2695 if (occlusionInfo.hasBlockingOcclusion) {
2696 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2697 occlusionInfo.obscuringUid);
2698 return false;
2699 }
2700 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2701 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2702 "%.2f, maximum allowed = %.2f)",
2703 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2704 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2705 return false;
2706 }
2707 return true;
2708}
2709
chaviw98318de2021-05-19 16:45:23 -05002710bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002711 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002712 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002713 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2714 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002715 if (windowHandle == otherHandle) {
2716 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002717 }
chaviw98318de2021-05-19 16:45:23 -05002718 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002719 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002720 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002721 return true;
2722 }
2723 }
2724 return false;
2725}
2726
chaviw98318de2021-05-19 16:45:23 -05002727bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002728 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002729 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2730 const WindowInfo* windowInfo = windowHandle->getInfo();
2731 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002732 if (windowHandle == otherHandle) {
2733 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002734 }
chaviw98318de2021-05-19 16:45:23 -05002735 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002736 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002737 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002738 return true;
2739 }
2740 }
2741 return false;
2742}
2743
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002744std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002745 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002746 if (applicationHandle != nullptr) {
2747 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002748 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002749 } else {
2750 return applicationHandle->getName();
2751 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002752 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002753 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002754 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002755 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002756 }
2757}
2758
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002759void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002760 if (eventEntry.type == EventEntry::Type::FOCUS ||
arthurhungb89ccb02020-12-30 16:19:01 +08002761 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED ||
2762 eventEntry.type == EventEntry::Type::DRAG) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002763 // Focus or pointer capture changed events are passed to apps, but do not represent user
2764 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002765 return;
2766 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002767 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002768 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002769 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002770 const WindowInfo* info = focusedWindowHandle->getInfo();
2771 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002772 if (DEBUG_DISPATCH_CYCLE) {
2773 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2774 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002775 return;
2776 }
2777 }
2778
2779 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002780 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002781 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002782 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2783 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002784 return;
2785 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002786
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002787 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002788 eventType = USER_ACTIVITY_EVENT_TOUCH;
2789 }
2790 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002791 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002792 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002793 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2794 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002795 return;
2796 }
2797 eventType = USER_ACTIVITY_EVENT_BUTTON;
2798 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002799 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07002800 case EventEntry::Type::TOUCH_MODE_CHANGED: {
2801 break;
2802 }
2803
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002804 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002805 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002806 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002807 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08002808 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2809 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002810 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08002811 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002812 break;
2813 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002814 }
2815
Prabir Pradhancef936d2021-07-21 16:17:52 +00002816 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2817 REQUIRES(mLock) {
2818 scoped_unlock unlock(mLock);
2819 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2820 };
2821 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002822}
2823
2824void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002825 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002826 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002827 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002828 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002829 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002830 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002831 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002832 ATRACE_NAME(message.c_str());
2833 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002834 if (DEBUG_DISPATCH_CYCLE) {
2835 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2836 "globalScaleFactor=%f, pointerIds=0x%x %s",
2837 connection->getInputChannelName().c_str(), inputTarget.flags,
2838 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2839 inputTarget.getPointerInfoString().c_str());
2840 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002841
2842 // Skip this event if the connection status is not normal.
2843 // We don't want to enqueue additional outbound events if the connection is broken.
2844 if (connection->status != Connection::STATUS_NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002845 if (DEBUG_DISPATCH_CYCLE) {
2846 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
2847 connection->getInputChannelName().c_str(), connection->getStatusLabel());
2848 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002849 return;
2850 }
2851
2852 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002853 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2854 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2855 "Entry type %s should not have FLAG_SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08002856 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002857
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002858 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002859 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002860 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002861 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002862 if (!splitMotionEntry) {
2863 return; // split event was dropped
2864 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002865 if (DEBUG_FOCUS) {
2866 ALOGD("channel '%s' ~ Split motion event.",
2867 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002868 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002869 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002870 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2871 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002872 return;
2873 }
2874 }
2875
2876 // Not splitting. Enqueue dispatch entries for the event as is.
2877 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2878}
2879
2880void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002881 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002882 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002883 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002884 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002885 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002886 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002887 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002888 ATRACE_NAME(message.c_str());
2889 }
2890
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002891 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002892
2893 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002894 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002895 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002896 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002897 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002898 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002899 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002900 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002901 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002902 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002903 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002904 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002905 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002906
2907 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002908 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002909 startDispatchCycleLocked(currentTime, connection);
2910 }
2911}
2912
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002913void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002914 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002915 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002916 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002917 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002918 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2919 connection->getInputChannelName().c_str(),
2920 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002921 ATRACE_NAME(message.c_str());
2922 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002923 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924 if (!(inputTargetFlags & dispatchMode)) {
2925 return;
2926 }
2927 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2928
2929 // This is a new event.
2930 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002931 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002932 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002933
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002934 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2935 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002936 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002937 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002938 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002939 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002940 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002941 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002942 dispatchEntry->resolvedAction = keyEntry.action;
2943 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002944
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002945 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2946 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002947 if (DEBUG_DISPATCH_CYCLE) {
2948 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
2949 "event",
2950 connection->getInputChannelName().c_str());
2951 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002952 return; // skip the inconsistent event
2953 }
2954 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002955 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002956
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002957 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002958 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002959 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2960 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2961 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2962 static_cast<int32_t>(IdGenerator::Source::OTHER);
2963 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002964 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2965 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2966 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2967 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2968 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2969 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2970 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2971 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2972 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2973 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2974 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002975 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002976 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002977 }
2978 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002979 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2980 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002981 if (DEBUG_DISPATCH_CYCLE) {
2982 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
2983 "enter event",
2984 connection->getInputChannelName().c_str());
2985 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00002986 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
2987 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002988 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2989 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002990
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002991 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002992 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2993 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2994 }
2995 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2996 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2997 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002998
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002999 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
3000 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003001 if (DEBUG_DISPATCH_CYCLE) {
3002 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
3003 "event",
3004 connection->getInputChannelName().c_str());
3005 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003006 return; // skip the inconsistent event
3007 }
3008
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003009 dispatchEntry->resolvedEventId =
3010 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
3011 ? mIdGenerator.nextId()
3012 : motionEntry.id;
3013 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
3014 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3015 ") to MotionEvent(id=0x%" PRIx32 ").",
3016 motionEntry.id, dispatchEntry->resolvedEventId);
3017 ATRACE_NAME(message.c_str());
3018 }
3019
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003020 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3021 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
3022 // Skip reporting pointer down outside focus to the policy.
3023 break;
3024 }
3025
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003026 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003027 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003028
3029 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003030 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003031 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003032 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003033 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3034 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003035 break;
3036 }
Chris Yef59a2f42020-10-16 12:55:26 -07003037 case EventEntry::Type::SENSOR: {
3038 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3039 break;
3040 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003041 case EventEntry::Type::CONFIGURATION_CHANGED:
3042 case EventEntry::Type::DEVICE_RESET: {
3043 LOG_ALWAYS_FATAL("%s events should not go to apps",
Dominik Laskowski75788452021-02-09 18:51:25 -08003044 ftl::enum_string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003045 break;
3046 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003047 }
3048
3049 // Remember that we are waiting for this dispatch to complete.
3050 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003051 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003052 }
3053
3054 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003055 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003056 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003057}
3058
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003059/**
3060 * This function is purely for debugging. It helps us understand where the user interaction
3061 * was taking place. For example, if user is touching launcher, we will see a log that user
3062 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3063 * We will see both launcher and wallpaper in that list.
3064 * Once the interaction with a particular set of connections starts, no new logs will be printed
3065 * until the set of interacted connections changes.
3066 *
3067 * The following items are skipped, to reduce the logspam:
3068 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3069 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3070 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3071 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3072 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003073 */
3074void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3075 const std::vector<InputTarget>& targets) {
3076 // Skip ACTION_UP events, and all events other than keys and motions
3077 if (entry.type == EventEntry::Type::KEY) {
3078 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3079 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3080 return;
3081 }
3082 } else if (entry.type == EventEntry::Type::MOTION) {
3083 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3084 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3085 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3086 return;
3087 }
3088 } else {
3089 return; // Not a key or a motion
3090 }
3091
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003092 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003093 std::vector<sp<Connection>> newConnections;
3094 for (const InputTarget& target : targets) {
3095 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3096 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3097 continue; // Skip windows that receive ACTION_OUTSIDE
3098 }
3099
3100 sp<IBinder> token = target.inputChannel->getConnectionToken();
3101 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003102 if (connection == nullptr) {
3103 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003104 }
3105 newConnectionTokens.insert(std::move(token));
3106 newConnections.emplace_back(connection);
3107 }
3108 if (newConnectionTokens == mInteractionConnectionTokens) {
3109 return; // no change
3110 }
3111 mInteractionConnectionTokens = newConnectionTokens;
3112
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003113 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003114 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003115 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003116 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003117 std::string message = "Interaction with: " + targetList;
3118 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003119 message += "<none>";
3120 }
3121 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3122}
3123
chaviwfd6d3512019-03-25 13:23:49 -07003124void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003125 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003126 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003127 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3128 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003129 return;
3130 }
3131
Vishnu Nairc519ff72021-01-21 08:23:08 -08003132 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003133 if (focusedToken == token) {
3134 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003135 return;
3136 }
3137
Prabir Pradhancef936d2021-07-21 16:17:52 +00003138 auto command = [this, token]() REQUIRES(mLock) {
3139 scoped_unlock unlock(mLock);
3140 mPolicy->onPointerDownOutsideFocus(token);
3141 };
3142 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003143}
3144
3145void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003146 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003147 if (ATRACE_ENABLED()) {
3148 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003149 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003150 ATRACE_NAME(message.c_str());
3151 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003152 if (DEBUG_DISPATCH_CYCLE) {
3153 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3154 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003155
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003156 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3157 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003158 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003159 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003160 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003161 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003162
3163 // Publish the event.
3164 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003165 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3166 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003167 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003168 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3169 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003170
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003171 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003172 status = connection->inputPublisher
3173 .publishKeyEvent(dispatchEntry->seq,
3174 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3175 keyEntry.source, keyEntry.displayId,
3176 std::move(hmac), dispatchEntry->resolvedAction,
3177 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3178 keyEntry.scanCode, keyEntry.metaState,
3179 keyEntry.repeatCount, keyEntry.downTime,
3180 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003181 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003182 }
3183
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003184 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003185 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003186
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003187 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003188 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003189
chaviw82357092020-01-28 13:13:06 -08003190 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003191 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003192 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3193 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003194 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003195 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3196 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003197 // Don't apply window scale here since we don't want scale to affect raw
3198 // coordinates. The scale will be sent back to the client and applied
3199 // later when requesting relative coordinates.
3200 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3201 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003202 }
3203 usingCoords = scaledCoords;
3204 }
3205 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003206 // We don't want the dispatch target to know.
3207 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003208 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003209 scaledCoords[i].clear();
3210 }
3211 usingCoords = scaledCoords;
3212 }
3213 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003214
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003215 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003216
3217 // Publish the motion event.
3218 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003219 .publishMotionEvent(dispatchEntry->seq,
3220 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003221 motionEntry.deviceId, motionEntry.source,
3222 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003223 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003224 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003225 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003226 motionEntry.edgeFlags, motionEntry.metaState,
3227 motionEntry.buttonState,
3228 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003229 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003230 motionEntry.xPrecision, motionEntry.yPrecision,
3231 motionEntry.xCursorPosition,
3232 motionEntry.yCursorPosition,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003233 dispatchEntry->rawTransform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003234 motionEntry.downTime, motionEntry.eventTime,
3235 motionEntry.pointerCount,
3236 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003237 break;
3238 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003239
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003240 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003241 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003242 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003243 focusEntry.id,
3244 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003245 mInTouchMode);
3246 break;
3247 }
3248
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003249 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3250 const TouchModeEntry& touchModeEntry =
3251 static_cast<const TouchModeEntry&>(eventEntry);
3252 status = connection->inputPublisher
3253 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3254 touchModeEntry.inTouchMode);
3255
3256 break;
3257 }
3258
Prabir Pradhan99987712020-11-10 18:43:05 -08003259 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3260 const auto& captureEntry =
3261 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3262 status = connection->inputPublisher
3263 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003264 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003265 break;
3266 }
3267
arthurhungb89ccb02020-12-30 16:19:01 +08003268 case EventEntry::Type::DRAG: {
3269 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3270 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3271 dragEntry.id, dragEntry.x,
3272 dragEntry.y,
3273 dragEntry.isExiting);
3274 break;
3275 }
3276
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003277 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003278 case EventEntry::Type::DEVICE_RESET:
3279 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003280 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003281 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003282 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003283 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003284 }
3285
3286 // Check the result.
3287 if (status) {
3288 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003289 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003290 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003291 "This is unexpected because the wait queue is empty, so the pipe "
3292 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003293 "event to it, status=%s(%d)",
3294 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3295 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003296 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3297 } else {
3298 // Pipe is full and we are waiting for the app to finish process some events
3299 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003300 if (DEBUG_DISPATCH_CYCLE) {
3301 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3302 "waiting for the application to catch up",
3303 connection->getInputChannelName().c_str());
3304 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003305 }
3306 } else {
3307 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003308 "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 }
3313 return;
3314 }
3315
3316 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003317 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3318 connection->outboundQueue.end(),
3319 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003320 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003321 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003322 if (connection->responsive) {
3323 mAnrTracker.insert(dispatchEntry->timeoutTime,
3324 connection->inputChannel->getConnectionToken());
3325 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003326 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327 }
3328}
3329
chaviw09c8d2d2020-08-24 15:48:26 -07003330std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3331 size_t size;
3332 switch (event.type) {
3333 case VerifiedInputEvent::Type::KEY: {
3334 size = sizeof(VerifiedKeyEvent);
3335 break;
3336 }
3337 case VerifiedInputEvent::Type::MOTION: {
3338 size = sizeof(VerifiedMotionEvent);
3339 break;
3340 }
3341 }
3342 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3343 return mHmacKeyManager.sign(start, size);
3344}
3345
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003346const std::array<uint8_t, 32> InputDispatcher::getSignature(
3347 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003348 const int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3349 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003350 // Only sign events up and down events as the purely move events
3351 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003352 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003353 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003354
3355 VerifiedMotionEvent verifiedEvent =
3356 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3357 verifiedEvent.actionMasked = actionMasked;
3358 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3359 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003360}
3361
3362const std::array<uint8_t, 32> InputDispatcher::getSignature(
3363 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3364 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3365 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3366 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003367 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003368}
3369
Michael Wrightd02c5b62014-02-10 15:10:22 -08003370void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003371 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003372 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003373 if (DEBUG_DISPATCH_CYCLE) {
3374 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3375 connection->getInputChannelName().c_str(), seq, toString(handled));
3376 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003377
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003378 if (connection->status == Connection::STATUS_BROKEN ||
3379 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003380 return;
3381 }
3382
3383 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003384 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3385 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3386 };
3387 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003388}
3389
3390void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003391 const sp<Connection>& connection,
3392 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003393 if (DEBUG_DISPATCH_CYCLE) {
3394 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3395 connection->getInputChannelName().c_str(), toString(notify));
3396 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003397
3398 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003399 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003400 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003401 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003402 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003403
3404 // The connection appears to be unrecoverably broken.
3405 // Ignore already broken or zombie connections.
3406 if (connection->status == Connection::STATUS_NORMAL) {
3407 connection->status = Connection::STATUS_BROKEN;
3408
3409 if (notify) {
3410 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003411 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3412 connection->getInputChannelName().c_str());
3413
3414 auto command = [this, connection]() REQUIRES(mLock) {
3415 if (connection->status == Connection::STATUS_ZOMBIE) return;
3416 scoped_unlock unlock(mLock);
3417 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3418 };
3419 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003420 }
3421 }
3422}
3423
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003424void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3425 while (!queue.empty()) {
3426 DispatchEntry* dispatchEntry = queue.front();
3427 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003428 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003429 }
3430}
3431
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003432void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003433 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003434 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003435 }
3436 delete dispatchEntry;
3437}
3438
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003439int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3440 std::scoped_lock _l(mLock);
3441 sp<Connection> connection = getConnectionLocked(connectionToken);
3442 if (connection == nullptr) {
3443 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3444 connectionToken.get(), events);
3445 return 0; // remove the callback
3446 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003447
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003448 bool notify;
3449 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3450 if (!(events & ALOOPER_EVENT_INPUT)) {
3451 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3452 "events=0x%x",
3453 connection->getInputChannelName().c_str(), events);
3454 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003455 }
3456
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003457 nsecs_t currentTime = now();
3458 bool gotOne = false;
3459 status_t status = OK;
3460 for (;;) {
3461 Result<InputPublisher::ConsumerResponse> result =
3462 connection->inputPublisher.receiveConsumerResponse();
3463 if (!result.ok()) {
3464 status = result.error().code();
3465 break;
3466 }
3467
3468 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3469 const InputPublisher::Finished& finish =
3470 std::get<InputPublisher::Finished>(*result);
3471 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3472 finish.consumeTime);
3473 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003474 if (shouldReportMetricsForConnection(*connection)) {
3475 const InputPublisher::Timeline& timeline =
3476 std::get<InputPublisher::Timeline>(*result);
3477 mLatencyTracker
3478 .trackGraphicsLatency(timeline.inputEventId,
3479 connection->inputChannel->getConnectionToken(),
3480 std::move(timeline.graphicsTimeline));
3481 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003482 }
3483 gotOne = true;
3484 }
3485 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003486 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003487 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003488 return 1;
3489 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003490 }
3491
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003492 notify = status != DEAD_OBJECT || !connection->monitor;
3493 if (notify) {
3494 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3495 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3496 status);
3497 }
3498 } else {
3499 // Monitor channels are never explicitly unregistered.
3500 // We do it automatically when the remote endpoint is closed so don't warn about them.
3501 const bool stillHaveWindowHandle =
3502 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3503 notify = !connection->monitor && stillHaveWindowHandle;
3504 if (notify) {
3505 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3506 connection->getInputChannelName().c_str(), events);
3507 }
3508 }
3509
3510 // Remove the channel.
3511 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3512 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003513}
3514
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003515void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003516 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003517 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003518 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003519 }
3520}
3521
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003522void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003523 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003524 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3525 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3526}
3527
3528void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3529 const CancelationOptions& options,
3530 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3531 for (const auto& it : monitorsByDisplay) {
3532 const std::vector<Monitor>& monitors = it.second;
3533 for (const Monitor& monitor : monitors) {
3534 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003535 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003536 }
3537}
3538
Michael Wrightd02c5b62014-02-10 15:10:22 -08003539void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003540 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003541 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003542 if (connection == nullptr) {
3543 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003544 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003545
3546 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003547}
3548
3549void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3550 const sp<Connection>& connection, const CancelationOptions& options) {
3551 if (connection->status == Connection::STATUS_BROKEN) {
3552 return;
3553 }
3554
3555 nsecs_t currentTime = now();
3556
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003557 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003558 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003559
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003560 if (cancelationEvents.empty()) {
3561 return;
3562 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003563 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3564 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3565 "with reality: %s, mode=%d.",
3566 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3567 options.mode);
3568 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003569
3570 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003571 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003572 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3573 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003574 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003575 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003576 target.globalScaleFactor = windowInfo->globalScaleFactor;
3577 }
3578 target.inputChannel = connection->inputChannel;
3579 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3580
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003581 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003582 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003583 switch (cancelationEventEntry->type) {
3584 case EventEntry::Type::KEY: {
3585 logOutboundKeyDetails("cancel - ",
3586 static_cast<const KeyEntry&>(*cancelationEventEntry));
3587 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003588 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003589 case EventEntry::Type::MOTION: {
3590 logOutboundMotionDetails("cancel - ",
3591 static_cast<const MotionEntry&>(*cancelationEventEntry));
3592 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003593 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003594 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003595 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003596 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3597 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003598 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08003599 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003600 break;
3601 }
3602 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003603 case EventEntry::Type::DEVICE_RESET:
3604 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003605 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003606 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003607 break;
3608 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003609 }
3610
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003611 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3612 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003613 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003614
3615 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003616}
3617
Svet Ganov5d3bc372020-01-26 23:11:07 -08003618void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3619 const sp<Connection>& connection) {
3620 if (connection->status == Connection::STATUS_BROKEN) {
3621 return;
3622 }
3623
3624 nsecs_t currentTime = now();
3625
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003626 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003627 connection->inputState.synthesizePointerDownEvents(currentTime);
3628
3629 if (downEvents.empty()) {
3630 return;
3631 }
3632
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003633 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003634 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3635 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003636 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003637
3638 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003639 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003640 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3641 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003642 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003643 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003644 target.globalScaleFactor = windowInfo->globalScaleFactor;
3645 }
3646 target.inputChannel = connection->inputChannel;
3647 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3648
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003649 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003650 switch (downEventEntry->type) {
3651 case EventEntry::Type::MOTION: {
3652 logOutboundMotionDetails("down - ",
3653 static_cast<const MotionEntry&>(*downEventEntry));
3654 break;
3655 }
3656
3657 case EventEntry::Type::KEY:
3658 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003659 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08003660 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003661 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003662 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003663 case EventEntry::Type::SENSOR:
3664 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003665 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003666 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003667 break;
3668 }
3669 }
3670
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003671 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3672 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003673 }
3674
3675 startDispatchCycleLocked(currentTime, connection);
3676}
3677
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003678std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3679 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003680 ALOG_ASSERT(pointerIds.value != 0);
3681
3682 uint32_t splitPointerIndexMap[MAX_POINTERS];
3683 PointerProperties splitPointerProperties[MAX_POINTERS];
3684 PointerCoords splitPointerCoords[MAX_POINTERS];
3685
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003686 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003687 uint32_t splitPointerCount = 0;
3688
3689 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003690 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003691 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003692 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003693 uint32_t pointerId = uint32_t(pointerProperties.id);
3694 if (pointerIds.hasBit(pointerId)) {
3695 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3696 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3697 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003698 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003699 splitPointerCount += 1;
3700 }
3701 }
3702
3703 if (splitPointerCount != pointerIds.count()) {
3704 // This is bad. We are missing some of the pointers that we expected to deliver.
3705 // Most likely this indicates that we received an ACTION_MOVE events that has
3706 // different pointer ids than we expected based on the previous ACTION_DOWN
3707 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3708 // in this way.
3709 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003710 "we expected there to be %d pointers. This probably means we received "
3711 "a broken sequence of pointer ids from the input device.",
3712 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003713 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003714 }
3715
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003716 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003717 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003718 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3719 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003720 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3721 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003722 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003723 uint32_t pointerId = uint32_t(pointerProperties.id);
3724 if (pointerIds.hasBit(pointerId)) {
3725 if (pointerIds.count() == 1) {
3726 // The first/last pointer went down/up.
3727 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003728 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003729 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3730 ? AMOTION_EVENT_ACTION_CANCEL
3731 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003732 } else {
3733 // A secondary pointer went down/up.
3734 uint32_t splitPointerIndex = 0;
3735 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3736 splitPointerIndex += 1;
3737 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003738 action = maskedAction |
3739 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003740 }
3741 } else {
3742 // An unrelated pointer changed.
3743 action = AMOTION_EVENT_ACTION_MOVE;
3744 }
3745 }
3746
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003747 int32_t newId = mIdGenerator.nextId();
3748 if (ATRACE_ENABLED()) {
3749 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3750 ") to MotionEvent(id=0x%" PRIx32 ").",
3751 originalMotionEntry.id, newId);
3752 ATRACE_NAME(message.c_str());
3753 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003754 std::unique_ptr<MotionEntry> splitMotionEntry =
3755 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3756 originalMotionEntry.deviceId, originalMotionEntry.source,
3757 originalMotionEntry.displayId,
3758 originalMotionEntry.policyFlags, action,
3759 originalMotionEntry.actionButton,
3760 originalMotionEntry.flags, originalMotionEntry.metaState,
3761 originalMotionEntry.buttonState,
3762 originalMotionEntry.classification,
3763 originalMotionEntry.edgeFlags,
3764 originalMotionEntry.xPrecision,
3765 originalMotionEntry.yPrecision,
3766 originalMotionEntry.xCursorPosition,
3767 originalMotionEntry.yCursorPosition,
3768 originalMotionEntry.downTime, splitPointerCount,
3769 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003770
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003771 if (originalMotionEntry.injectionState) {
3772 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003773 splitMotionEntry->injectionState->refCount += 1;
3774 }
3775
3776 return splitMotionEntry;
3777}
3778
3779void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003780 if (DEBUG_INBOUND_EVENT_DETAILS) {
3781 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3782 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003783
3784 bool needWake;
3785 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003786 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003787
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003788 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3789 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3790 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003791 } // release lock
3792
3793 if (needWake) {
3794 mLooper->wake();
3795 }
3796}
3797
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003798/**
3799 * If one of the meta shortcuts is detected, process them here:
3800 * Meta + Backspace -> generate BACK
3801 * Meta + Enter -> generate HOME
3802 * This will potentially overwrite keyCode and metaState.
3803 */
3804void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003805 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003806 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3807 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3808 if (keyCode == AKEYCODE_DEL) {
3809 newKeyCode = AKEYCODE_BACK;
3810 } else if (keyCode == AKEYCODE_ENTER) {
3811 newKeyCode = AKEYCODE_HOME;
3812 }
3813 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003814 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003815 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003816 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003817 keyCode = newKeyCode;
3818 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3819 }
3820 } else if (action == AKEY_EVENT_ACTION_UP) {
3821 // In order to maintain a consistent stream of up and down events, check to see if the key
3822 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3823 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003824 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003825 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003826 auto replacementIt = mReplacedKeys.find(replacement);
3827 if (replacementIt != mReplacedKeys.end()) {
3828 keyCode = replacementIt->second;
3829 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003830 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3831 }
3832 }
3833}
3834
Michael Wrightd02c5b62014-02-10 15:10:22 -08003835void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003836 if (DEBUG_INBOUND_EVENT_DETAILS) {
3837 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3838 "policyFlags=0x%x, action=0x%x, "
3839 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3840 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3841 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3842 args->downTime);
3843 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003844 if (!validateKeyEvent(args->action)) {
3845 return;
3846 }
3847
3848 uint32_t policyFlags = args->policyFlags;
3849 int32_t flags = args->flags;
3850 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003851 // InputDispatcher tracks and generates key repeats on behalf of
3852 // whatever notifies it, so repeatCount should always be set to 0
3853 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003854 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3855 policyFlags |= POLICY_FLAG_VIRTUAL;
3856 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3857 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003858 if (policyFlags & POLICY_FLAG_FUNCTION) {
3859 metaState |= AMETA_FUNCTION_ON;
3860 }
3861
3862 policyFlags |= POLICY_FLAG_TRUSTED;
3863
Michael Wright78f24442014-08-06 15:55:28 -07003864 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003865 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003866
Michael Wrightd02c5b62014-02-10 15:10:22 -08003867 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003868 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003869 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3870 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003871
Michael Wright2b3c3302018-03-02 17:19:13 +00003872 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003873 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003874 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3875 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003876 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003877 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003878
Michael Wrightd02c5b62014-02-10 15:10:22 -08003879 bool needWake;
3880 { // acquire lock
3881 mLock.lock();
3882
3883 if (shouldSendKeyToInputFilterLocked(args)) {
3884 mLock.unlock();
3885
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003886 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003887 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3888 return; // event was consumed by the filter
3889 }
3890
3891 mLock.lock();
3892 }
3893
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003894 std::unique_ptr<KeyEntry> newEntry =
3895 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3896 args->displayId, policyFlags, args->action, flags,
3897 keyCode, args->scanCode, metaState, repeatCount,
3898 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003899
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003900 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003901 mLock.unlock();
3902 } // release lock
3903
3904 if (needWake) {
3905 mLooper->wake();
3906 }
3907}
3908
3909bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3910 return mInputFilterEnabled;
3911}
3912
3913void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003914 if (DEBUG_INBOUND_EVENT_DETAILS) {
3915 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3916 "displayId=%" PRId32 ", policyFlags=0x%x, "
3917 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3918 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
3919 "yCursorPosition=%f, downTime=%" PRId64,
3920 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3921 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3922 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3923 args->xCursorPosition, args->yCursorPosition, args->downTime);
3924 for (uint32_t i = 0; i < args->pointerCount; i++) {
3925 ALOGD(" Pointer %d: id=%d, toolType=%d, "
3926 "x=%f, y=%f, pressure=%f, size=%f, "
3927 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3928 "orientation=%f",
3929 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3930 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3931 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3932 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3933 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3934 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3935 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3936 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3937 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3938 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
3939 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003940 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003941 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3942 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003943 return;
3944 }
3945
3946 uint32_t policyFlags = args->policyFlags;
3947 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003948
3949 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003950 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003951 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3952 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003953 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003954 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003955
3956 bool needWake;
3957 { // acquire lock
3958 mLock.lock();
3959
3960 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07003961 ui::Transform displayTransform;
3962 if (const auto it = mDisplayInfos.find(args->displayId); it != mDisplayInfos.end()) {
3963 displayTransform = it->second.transform;
3964 }
3965
Michael Wrightd02c5b62014-02-10 15:10:22 -08003966 mLock.unlock();
3967
3968 MotionEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003969 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3970 args->action, args->actionButton, args->flags, args->edgeFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003971 args->metaState, args->buttonState, args->classification,
Prabir Pradhan81420cc2021-09-06 10:28:50 -07003972 displayTransform, args->xPrecision, args->yPrecision,
3973 args->xCursorPosition, args->yCursorPosition, displayTransform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003974 args->downTime, args->eventTime, args->pointerCount,
3975 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976
3977 policyFlags |= POLICY_FLAG_FILTERED;
3978 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3979 return; // event was consumed by the filter
3980 }
3981
3982 mLock.lock();
3983 }
3984
3985 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003986 std::unique_ptr<MotionEntry> newEntry =
3987 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3988 args->source, args->displayId, policyFlags,
3989 args->action, args->actionButton, args->flags,
3990 args->metaState, args->buttonState,
3991 args->classification, args->edgeFlags,
3992 args->xPrecision, args->yPrecision,
3993 args->xCursorPosition, args->yCursorPosition,
3994 args->downTime, args->pointerCount,
3995 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003996
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00003997 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
3998 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
3999 !mInputFilterEnabled) {
4000 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
4001 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
4002 }
4003
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004004 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004005 mLock.unlock();
4006 } // release lock
4007
4008 if (needWake) {
4009 mLooper->wake();
4010 }
4011}
4012
Chris Yef59a2f42020-10-16 12:55:26 -07004013void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004014 if (DEBUG_INBOUND_EVENT_DETAILS) {
4015 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4016 " sensorType=%s",
4017 args->id, args->eventTime, args->deviceId, args->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08004018 ftl::enum_string(args->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004019 }
Chris Yef59a2f42020-10-16 12:55:26 -07004020
4021 bool needWake;
4022 { // acquire lock
4023 mLock.lock();
4024
4025 // Just enqueue a new sensor event.
4026 std::unique_ptr<SensorEntry> newEntry =
4027 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
4028 args->source, 0 /* policyFlags*/, args->hwTimestamp,
4029 args->sensorType, args->accuracy,
4030 args->accuracyChanged, args->values);
4031
4032 needWake = enqueueInboundEventLocked(std::move(newEntry));
4033 mLock.unlock();
4034 } // release lock
4035
4036 if (needWake) {
4037 mLooper->wake();
4038 }
4039}
4040
Chris Yefb552902021-02-03 17:18:37 -08004041void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004042 if (DEBUG_INBOUND_EVENT_DETAILS) {
4043 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
4044 args->deviceId, args->isOn);
4045 }
Chris Yefb552902021-02-03 17:18:37 -08004046 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
4047}
4048
Michael Wrightd02c5b62014-02-10 15:10:22 -08004049bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08004050 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004051}
4052
4053void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004054 if (DEBUG_INBOUND_EVENT_DETAILS) {
4055 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4056 "switchMask=0x%08x",
4057 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
4058 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004059
4060 uint32_t policyFlags = args->policyFlags;
4061 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004062 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004063}
4064
4065void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004066 if (DEBUG_INBOUND_EVENT_DETAILS) {
4067 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
4068 args->deviceId);
4069 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004070
4071 bool needWake;
4072 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004073 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004074
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004075 std::unique_ptr<DeviceResetEntry> newEntry =
4076 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
4077 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004078 } // release lock
4079
4080 if (needWake) {
4081 mLooper->wake();
4082 }
4083}
4084
Prabir Pradhan7e186182020-11-10 13:56:45 -08004085void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004086 if (DEBUG_INBOUND_EVENT_DETAILS) {
4087 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004088 args->request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004089 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004090
Prabir Pradhan99987712020-11-10 18:43:05 -08004091 bool needWake;
4092 { // acquire lock
4093 std::scoped_lock _l(mLock);
4094 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004095 args->request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004096 needWake = enqueueInboundEventLocked(std::move(entry));
4097 } // release lock
4098
4099 if (needWake) {
4100 mLooper->wake();
4101 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004102}
4103
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004104InputEventInjectionResult InputDispatcher::injectInputEvent(
4105 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4106 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004107 if (DEBUG_INBOUND_EVENT_DETAILS) {
4108 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
4109 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4110 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
4111 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004112 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004113
4114 policyFlags |= POLICY_FLAG_INJECTED;
4115 if (hasInjectionPermission(injectorPid, injectorUid)) {
4116 policyFlags |= POLICY_FLAG_TRUSTED;
4117 }
4118
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004119 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004120 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4121 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4122 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4123 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4124 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004125 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004126 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004127 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004128 }
4129
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004130 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004131 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004132 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004133 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4134 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004135 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004136 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004137 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004138
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004139 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004140 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4141 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4142 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004143 int32_t keyCode = incomingKey.getKeyCode();
4144 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004145 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004146 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004147 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004148 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004149 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4150 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4151 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004152
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004153 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4154 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004155 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004156
4157 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4158 android::base::Timer t;
4159 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4160 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4161 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4162 std::to_string(t.duration().count()).c_str());
4163 }
4164 }
4165
4166 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004167 std::unique_ptr<KeyEntry> injectedEntry =
4168 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004169 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004170 incomingKey.getDisplayId(), policyFlags, action,
4171 flags, keyCode, incomingKey.getScanCode(), metaState,
4172 incomingKey.getRepeatCount(),
4173 incomingKey.getDownTime());
4174 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004175 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004176 }
4177
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004178 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004179 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004180 const int32_t action = motionEvent.getAction();
4181 const bool isPointerEvent =
4182 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4183 // If a pointer event has no displayId specified, inject it to the default display.
4184 const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
4185 ? ADISPLAY_ID_DEFAULT
4186 : event->getDisplayId();
4187 const size_t pointerCount = motionEvent.getPointerCount();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004188 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004189 const int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004190 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004191 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004192 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004193 }
4194
4195 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004196 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004197 android::base::Timer t;
4198 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4199 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4200 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4201 std::to_string(t.duration().count()).c_str());
4202 }
4203 }
4204
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004205 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4206 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4207 }
4208
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004209 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004210 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4211 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004212 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004213 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4214 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004215 displayId, policyFlags, action, actionButton,
4216 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004217 motionEvent.getButtonState(),
4218 motionEvent.getClassification(),
4219 motionEvent.getEdgeFlags(),
4220 motionEvent.getXPrecision(),
4221 motionEvent.getYPrecision(),
4222 motionEvent.getRawXCursorPosition(),
4223 motionEvent.getRawYCursorPosition(),
4224 motionEvent.getDownTime(), uint32_t(pointerCount),
4225 pointerProperties, samplePointerCoords,
4226 motionEvent.getXOffset(),
4227 motionEvent.getYOffset());
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004228 transformMotionEntryForInjectionLocked(*injectedEntry);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004229 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004230 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004231 sampleEventTimes += 1;
4232 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004233 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004234 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4235 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004236 displayId, policyFlags, action, actionButton,
4237 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004238 motionEvent.getButtonState(),
4239 motionEvent.getClassification(),
4240 motionEvent.getEdgeFlags(),
4241 motionEvent.getXPrecision(),
4242 motionEvent.getYPrecision(),
4243 motionEvent.getRawXCursorPosition(),
4244 motionEvent.getRawYCursorPosition(),
4245 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004246 uint32_t(pointerCount), pointerProperties,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004247 samplePointerCoords, motionEvent.getXOffset(),
4248 motionEvent.getYOffset());
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004249 transformMotionEntryForInjectionLocked(*nextInjectedEntry);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004250 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004251 }
4252 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004253 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004254
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004255 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004256 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004257 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004258 }
4259
4260 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004261 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004262 injectionState->injectionIsAsync = true;
4263 }
4264
4265 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004266 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004267
4268 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004269 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004270 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004271 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004272 }
4273
4274 mLock.unlock();
4275
4276 if (needWake) {
4277 mLooper->wake();
4278 }
4279
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004280 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004281 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004282 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004283
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004284 if (syncMode == InputEventInjectionSync::NONE) {
4285 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004286 } else {
4287 for (;;) {
4288 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004289 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004290 break;
4291 }
4292
4293 nsecs_t remainingTimeout = endTime - now();
4294 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004295 if (DEBUG_INJECTION) {
4296 ALOGD("injectInputEvent - Timed out waiting for injection result "
4297 "to become available.");
4298 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004299 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004300 break;
4301 }
4302
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004303 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004304 }
4305
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004306 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4307 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004308 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004309 if (DEBUG_INJECTION) {
4310 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4311 injectionState->pendingForegroundDispatches);
4312 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004313 nsecs_t remainingTimeout = endTime - now();
4314 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004315 if (DEBUG_INJECTION) {
4316 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4317 "dispatches to finish.");
4318 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004319 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004320 break;
4321 }
4322
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004323 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004324 }
4325 }
4326 }
4327
4328 injectionState->release();
4329 } // release lock
4330
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004331 if (DEBUG_INJECTION) {
4332 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
4333 injectionResult, injectorPid, injectorUid);
4334 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004335
4336 return injectionResult;
4337}
4338
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004339std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004340 std::array<uint8_t, 32> calculatedHmac;
4341 std::unique_ptr<VerifiedInputEvent> result;
4342 switch (event.getType()) {
4343 case AINPUT_EVENT_TYPE_KEY: {
4344 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4345 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4346 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004347 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004348 break;
4349 }
4350 case AINPUT_EVENT_TYPE_MOTION: {
4351 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4352 VerifiedMotionEvent verifiedMotionEvent =
4353 verifiedMotionEventFromMotionEvent(motionEvent);
4354 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004355 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004356 break;
4357 }
4358 default: {
4359 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4360 return nullptr;
4361 }
4362 }
4363 if (calculatedHmac == INVALID_HMAC) {
4364 return nullptr;
4365 }
4366 if (calculatedHmac != event.getHmac()) {
4367 return nullptr;
4368 }
4369 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004370}
4371
Michael Wrightd02c5b62014-02-10 15:10:22 -08004372bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004373 return injectorUid == 0 ||
4374 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004375}
4376
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004377void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004378 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004379 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004380 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004381 if (DEBUG_INJECTION) {
4382 ALOGD("Setting input event injection result to %d. "
4383 "injectorPid=%d, injectorUid=%d",
4384 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
4385 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004386
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004387 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004388 // Log the outcome since the injector did not wait for the injection result.
4389 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004390 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004391 ALOGV("Asynchronous input event injection succeeded.");
4392 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004393 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004394 ALOGW("Asynchronous input event injection failed.");
4395 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004396 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004397 ALOGW("Asynchronous input event injection permission denied.");
4398 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004399 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004400 ALOGW("Asynchronous input event injection timed out.");
4401 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004402 case InputEventInjectionResult::PENDING:
4403 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4404 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004405 }
4406 }
4407
4408 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004409 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004410 }
4411}
4412
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004413void InputDispatcher::transformMotionEntryForInjectionLocked(MotionEntry& entry) const {
4414 const bool isRelativeMouseEvent = isFromSource(entry.source, AINPUT_SOURCE_MOUSE_RELATIVE);
4415 if (!isRelativeMouseEvent && !isFromSource(entry.source, AINPUT_SOURCE_CLASS_POINTER)) {
4416 return;
4417 }
4418
4419 // Input injection works in the logical display coordinate space, but the input pipeline works
4420 // display space, so we need to transform the injected events accordingly.
4421 const auto it = mDisplayInfos.find(entry.displayId);
4422 if (it == mDisplayInfos.end()) return;
4423 const auto& transformToDisplay = it->second.transform.inverse();
4424
4425 for (uint32_t i = 0; i < entry.pointerCount; i++) {
4426 PointerCoords& pc = entry.pointerCoords[i];
4427 const auto xy = isRelativeMouseEvent
4428 ? transformWithoutTranslation(transformToDisplay, pc.getX(), pc.getY())
4429 : transformToDisplay.transform(pc.getXYValue());
4430 pc.setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
4431 pc.setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
4432
4433 // Axes with relative values never represent points on a screen, so they should never have
4434 // translation applied. If a device does not report relative values, these values are always
4435 // 0, and will remain unaffected by the following operation.
4436 const auto rel =
4437 transformWithoutTranslation(transformToDisplay,
4438 pc.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
4439 pc.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
4440 pc.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, rel.x);
4441 pc.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, rel.y);
4442 }
4443}
4444
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004445void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4446 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004447 if (injectionState) {
4448 injectionState->pendingForegroundDispatches += 1;
4449 }
4450}
4451
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004452void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4453 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004454 if (injectionState) {
4455 injectionState->pendingForegroundDispatches -= 1;
4456
4457 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004458 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004459 }
4460 }
4461}
4462
chaviw98318de2021-05-19 16:45:23 -05004463const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004464 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004465 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004466 auto it = mWindowHandlesByDisplay.find(displayId);
4467 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004468}
4469
chaviw98318de2021-05-19 16:45:23 -05004470sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004471 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004472 if (windowHandleToken == nullptr) {
4473 return nullptr;
4474 }
4475
Arthur Hungb92218b2018-08-14 12:00:21 +08004476 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004477 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4478 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004479 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004480 return windowHandle;
4481 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004482 }
4483 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004484 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004485}
4486
chaviw98318de2021-05-19 16:45:23 -05004487sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4488 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004489 if (windowHandleToken == nullptr) {
4490 return nullptr;
4491 }
4492
chaviw98318de2021-05-19 16:45:23 -05004493 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004494 if (windowHandle->getToken() == windowHandleToken) {
4495 return windowHandle;
4496 }
4497 }
4498 return nullptr;
4499}
4500
chaviw98318de2021-05-19 16:45:23 -05004501sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4502 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004503 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004504 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4505 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004506 if (handle->getId() == windowHandle->getId() &&
4507 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004508 if (windowHandle->getInfo()->displayId != it.first) {
4509 ALOGE("Found window %s in display %" PRId32
4510 ", but it should belong to display %" PRId32,
4511 windowHandle->getName().c_str(), it.first,
4512 windowHandle->getInfo()->displayId);
4513 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004514 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004515 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004516 }
4517 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004518 return nullptr;
4519}
4520
chaviw98318de2021-05-19 16:45:23 -05004521sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004522 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4523 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004524}
4525
chaviw98318de2021-05-19 16:45:23 -05004526bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004527 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4528 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004529 windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004530 if (connection != nullptr && noInputChannel) {
4531 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4532 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4533 return false;
4534 }
4535
4536 if (connection == nullptr) {
4537 if (!noInputChannel) {
4538 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4539 }
4540 return false;
4541 }
4542 if (!connection->responsive) {
4543 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4544 return false;
4545 }
4546 return true;
4547}
4548
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004549std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4550 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004551 auto connectionIt = mConnectionsByToken.find(token);
4552 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004553 return nullptr;
4554 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004555 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004556}
4557
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004558void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004559 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4560 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004561 // Remove all handles on a display if there are no windows left.
4562 mWindowHandlesByDisplay.erase(displayId);
4563 return;
4564 }
4565
4566 // Since we compare the pointer of input window handles across window updates, we need
4567 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004568 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4569 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4570 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004571 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004572 }
4573
chaviw98318de2021-05-19 16:45:23 -05004574 std::vector<sp<WindowInfoHandle>> newHandles;
4575 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05004576 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004577 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004578 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004579 info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
4580 const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
4581 !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004582 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004583 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004584 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004585 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004586 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004587 }
4588
4589 if (info->displayId != displayId) {
4590 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4591 handle->getName().c_str(), displayId, info->displayId);
4592 continue;
4593 }
4594
Robert Carredd13602020-04-13 17:24:34 -07004595 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4596 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004597 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004598 oldHandle->updateFrom(handle);
4599 newHandles.push_back(oldHandle);
4600 } else {
4601 newHandles.push_back(handle);
4602 }
4603 }
4604
4605 // Insert or replace
4606 mWindowHandlesByDisplay[displayId] = newHandles;
4607}
4608
Arthur Hung72d8dc32020-03-28 00:48:39 +00004609void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004610 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07004611 // TODO(b/198444055): Remove setInputWindows from InputDispatcher.
Arthur Hung72d8dc32020-03-28 00:48:39 +00004612 { // acquire lock
4613 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004614 for (const auto& [displayId, handles] : handlesPerDisplay) {
4615 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004616 }
4617 }
4618 // Wake up poll loop since it may need to make new input dispatching choices.
4619 mLooper->wake();
4620}
4621
Arthur Hungb92218b2018-08-14 12:00:21 +08004622/**
4623 * Called from InputManagerService, update window handle list by displayId that can receive input.
4624 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4625 * If set an empty list, remove all handles from the specific display.
4626 * For focused handle, check if need to change and send a cancel event to previous one.
4627 * For removed handle, check if need to send a cancel event if already in touch.
4628 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004629void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004630 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004631 if (DEBUG_FOCUS) {
4632 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004633 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004634 windowList += iwh->getName() + " ";
4635 }
4636 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4637 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004638
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004639 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
chaviw98318de2021-05-19 16:45:23 -05004640 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004641 const bool noInputWindow =
chaviw98318de2021-05-19 16:45:23 -05004642 window->getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004643 if (noInputWindow && window->getToken() != nullptr) {
4644 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4645 window->getName().c_str());
4646 window->releaseChannel();
4647 }
4648 }
4649
Arthur Hung72d8dc32020-03-28 00:48:39 +00004650 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004651 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004652
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004653 // Save the old windows' orientation by ID before it gets updated.
4654 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004655 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004656 oldWindowOrientations.emplace(handle->getId(),
4657 handle->getInfo()->transform.getOrientation());
4658 }
4659
chaviw98318de2021-05-19 16:45:23 -05004660 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004661
chaviw98318de2021-05-19 16:45:23 -05004662 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004663 if (mLastHoverWindowHandle &&
4664 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4665 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004666 mLastHoverWindowHandle = nullptr;
4667 }
4668
Vishnu Nairc519ff72021-01-21 08:23:08 -08004669 std::optional<FocusResolver::FocusChanges> changes =
4670 mFocusResolver.setInputWindows(displayId, windowHandles);
4671 if (changes) {
4672 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004673 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004674
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004675 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4676 mTouchStatesByDisplay.find(displayId);
4677 if (stateIt != mTouchStatesByDisplay.end()) {
4678 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004679 for (size_t i = 0; i < state.windows.size();) {
4680 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004681 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004682 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004683 ALOGD("Touched window was removed: %s in display %" PRId32,
4684 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004685 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004686 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004687 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4688 if (touchedInputChannel != nullptr) {
4689 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4690 "touched window was removed");
4691 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004692 // Since we are about to drop the touch, cancel the events for the wallpaper as
4693 // well.
4694 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND &&
4695 touchedWindow.windowHandle->getInfo()->hasWallpaper) {
4696 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
4697 if (wallpaper != nullptr) {
4698 sp<Connection> wallpaperConnection =
4699 getConnectionLocked(wallpaper->getToken());
4700 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection,
4701 options);
4702 }
4703 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004704 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004705 state.windows.erase(state.windows.begin() + i);
4706 } else {
4707 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004708 }
4709 }
arthurhungb89ccb02020-12-30 16:19:01 +08004710
arthurhung6d4bed92021-03-17 11:59:33 +08004711 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004712 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004713 if (mDragState &&
4714 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004715 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004716 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004717 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004718 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004719
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004720 if (isPerWindowInputRotationEnabled()) {
4721 // Determine if the orientation of any of the input windows have changed, and cancel all
4722 // pointer events if necessary.
chaviw98318de2021-05-19 16:45:23 -05004723 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4724 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004725 if (newWindowHandle != nullptr &&
4726 newWindowHandle->getInfo()->transform.getOrientation() !=
4727 oldWindowOrientations[oldWindowHandle->getId()]) {
4728 std::shared_ptr<InputChannel> inputChannel =
4729 getInputChannelLocked(newWindowHandle->getToken());
4730 if (inputChannel != nullptr) {
4731 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4732 "touched window's orientation changed");
4733 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4734 }
4735 }
4736 }
4737 }
4738
Arthur Hung72d8dc32020-03-28 00:48:39 +00004739 // Release information for windows that are no longer present.
4740 // This ensures that unused input channels are released promptly.
4741 // Otherwise, they might stick around until the window handle is destroyed
4742 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004743 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004744 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004745 if (DEBUG_FOCUS) {
4746 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004747 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004748 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004749 // To avoid making too many calls into the compat framework, only
4750 // check for window flags when windows are going away.
4751 // TODO(b/157929241) : delete this. This is only needed temporarily
4752 // in order to gather some data about the flag usage
chaviw98318de2021-05-19 16:45:23 -05004753 if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004754 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4755 oldWindowHandle->getName().c_str());
4756 if (mCompatService != nullptr) {
4757 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4758 oldWindowHandle->getInfo()->ownerUid);
4759 }
4760 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004761 }
chaviw291d88a2019-02-14 10:33:58 -08004762 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004763}
4764
4765void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004766 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004767 if (DEBUG_FOCUS) {
4768 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4769 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4770 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004771 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004772 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004773 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004774 } // release lock
4775
4776 // Wake up poll loop since it may need to make new input dispatching choices.
4777 mLooper->wake();
4778}
4779
Vishnu Nair599f1412021-06-21 10:39:58 -07004780void InputDispatcher::setFocusedApplicationLocked(
4781 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4782 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4783 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4784
4785 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4786 return; // This application is already focused. No need to wake up or change anything.
4787 }
4788
4789 // Set the new application handle.
4790 if (inputApplicationHandle != nullptr) {
4791 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4792 } else {
4793 mFocusedApplicationHandlesByDisplay.erase(displayId);
4794 }
4795
4796 // No matter what the old focused application was, stop waiting on it because it is
4797 // no longer focused.
4798 resetNoFocusedWindowTimeoutLocked();
4799}
4800
Tiger Huang721e26f2018-07-24 22:26:19 +08004801/**
4802 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4803 * the display not specified.
4804 *
4805 * We track any unreleased events for each window. If a window loses the ability to receive the
4806 * released event, we will send a cancel event to it. So when the focused display is changed, we
4807 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4808 * display. The display-specified events won't be affected.
4809 */
4810void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004811 if (DEBUG_FOCUS) {
4812 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4813 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004814 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004815 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004816
4817 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004818 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004819 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004820 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004821 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004822 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004823 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004824 CancelationOptions
4825 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4826 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004827 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004828 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4829 }
4830 }
4831 mFocusedDisplayId = displayId;
4832
Chris Ye3c2d6f52020-08-09 10:39:48 -07004833 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004834 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004835 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004836
Vishnu Nairad321cd2020-08-20 16:40:21 -07004837 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004838 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004839 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004840 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004841 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004842 }
4843 }
4844 }
4845
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004846 if (DEBUG_FOCUS) {
4847 logDispatchStateLocked();
4848 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004849 } // release lock
4850
4851 // Wake up poll loop since it may need to make new input dispatching choices.
4852 mLooper->wake();
4853}
4854
Michael Wrightd02c5b62014-02-10 15:10:22 -08004855void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004856 if (DEBUG_FOCUS) {
4857 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4858 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004859
4860 bool changed;
4861 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004862 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004863
4864 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4865 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004866 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004867 }
4868
4869 if (mDispatchEnabled && !enabled) {
4870 resetAndDropEverythingLocked("dispatcher is being disabled");
4871 }
4872
4873 mDispatchEnabled = enabled;
4874 mDispatchFrozen = frozen;
4875 changed = true;
4876 } else {
4877 changed = false;
4878 }
4879
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004880 if (DEBUG_FOCUS) {
4881 logDispatchStateLocked();
4882 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004883 } // release lock
4884
4885 if (changed) {
4886 // Wake up poll loop since it may need to make new input dispatching choices.
4887 mLooper->wake();
4888 }
4889}
4890
4891void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004892 if (DEBUG_FOCUS) {
4893 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4894 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004895
4896 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004897 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004898
4899 if (mInputFilterEnabled == enabled) {
4900 return;
4901 }
4902
4903 mInputFilterEnabled = enabled;
4904 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4905 } // release lock
4906
4907 // Wake up poll loop since there might be work to do to drop everything.
4908 mLooper->wake();
4909}
4910
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004911void InputDispatcher::setInTouchMode(bool inTouchMode) {
4912 std::scoped_lock lock(mLock);
4913 mInTouchMode = inTouchMode;
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004914 // TODO(b/193718270): Fire TouchModeEvent here.
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004915}
4916
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004917void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4918 if (opacity < 0 || opacity > 1) {
4919 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4920 return;
4921 }
4922
4923 std::scoped_lock lock(mLock);
4924 mMaximumObscuringOpacityForTouch = opacity;
4925}
4926
4927void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4928 std::scoped_lock lock(mLock);
4929 mBlockUntrustedTouchesMode = mode;
4930}
4931
Arthur Hungabbb9d82021-09-01 14:52:30 +00004932std::pair<TouchState*, TouchedWindow*> InputDispatcher::findTouchStateAndWindowLocked(
4933 const sp<IBinder>& token) {
4934 for (auto& [displayId, state] : mTouchStatesByDisplay) {
4935 for (TouchedWindow& w : state.windows) {
4936 if (w.windowHandle->getToken() == token) {
4937 return std::make_pair(&state, &w);
4938 }
4939 }
4940 }
4941 return std::make_pair(nullptr, nullptr);
4942}
4943
arthurhungb89ccb02020-12-30 16:19:01 +08004944bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4945 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004946 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004947 if (DEBUG_FOCUS) {
4948 ALOGD("Trivial transfer to same window.");
4949 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004950 return true;
4951 }
4952
Michael Wrightd02c5b62014-02-10 15:10:22 -08004953 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004954 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004955
Arthur Hungabbb9d82021-09-01 14:52:30 +00004956 // Find the target touch state and touched window by fromToken.
4957 auto [state, touchedWindow] = findTouchStateAndWindowLocked(fromToken);
4958 if (state == nullptr || touchedWindow == nullptr) {
4959 ALOGD("Focus transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004960 return false;
4961 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00004962
4963 const int32_t displayId = state->displayId;
4964 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
4965 if (toWindowHandle == nullptr) {
4966 ALOGW("Cannot transfer focus because to window not found.");
4967 return false;
4968 }
4969
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004970 if (DEBUG_FOCUS) {
4971 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00004972 touchedWindow->windowHandle->getName().c_str(),
4973 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004974 }
4975
Arthur Hungabbb9d82021-09-01 14:52:30 +00004976 // Erase old window.
4977 int32_t oldTargetFlags = touchedWindow->targetFlags;
4978 BitSet32 pointerIds = touchedWindow->pointerIds;
4979 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004980
Arthur Hungabbb9d82021-09-01 14:52:30 +00004981 // Add new window.
4982 int32_t newTargetFlags = oldTargetFlags &
4983 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4984 InputTarget::FLAG_DISPATCH_AS_IS);
4985 state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004986
Arthur Hungabbb9d82021-09-01 14:52:30 +00004987 // Store the dragging window.
4988 if (isDragDrop) {
4989 mDragState = std::make_unique<DragState>(toWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004990 }
4991
Arthur Hungabbb9d82021-09-01 14:52:30 +00004992 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004993 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4994 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004995 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004996 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004997 CancelationOptions
4998 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4999 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005000 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08005001 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005002 }
5003
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005004 if (DEBUG_FOCUS) {
5005 logDispatchStateLocked();
5006 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005007 } // release lock
5008
5009 // Wake up poll loop since it may need to make new input dispatching choices.
5010 mLooper->wake();
5011 return true;
5012}
5013
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005014// Binder call
5015bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
5016 sp<IBinder> fromToken;
5017 { // acquire lock
5018 std::scoped_lock _l(mLock);
5019
Arthur Hungabbb9d82021-09-01 14:52:30 +00005020 auto it = std::find_if(mTouchStatesByDisplay.begin(), mTouchStatesByDisplay.end(),
5021 [](const auto& pair) { return pair.second.windows.size() == 1; });
5022 if (it == mTouchStatesByDisplay.end()) {
5023 ALOGW("Cannot transfer touch state because there is no exact window being touched");
5024 return false;
5025 }
5026 const int32_t displayId = it->first;
5027 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005028 if (toWindowHandle == nullptr) {
5029 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
5030 return false;
5031 }
5032
Arthur Hungabbb9d82021-09-01 14:52:30 +00005033 TouchState& state = it->second;
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005034 const TouchedWindow& touchedWindow = state.windows[0];
5035 fromToken = touchedWindow.windowHandle->getToken();
5036 } // release lock
5037
5038 return transferTouchFocus(fromToken, destChannelToken);
5039}
5040
Michael Wrightd02c5b62014-02-10 15:10:22 -08005041void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005042 if (DEBUG_FOCUS) {
5043 ALOGD("Resetting and dropping all events (%s).", reason);
5044 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005045
5046 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
5047 synthesizeCancelationEventsForAllConnectionsLocked(options);
5048
5049 resetKeyRepeatLocked();
5050 releasePendingEventLocked();
5051 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005052 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005053
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005054 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005055 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005056 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07005057 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005058}
5059
5060void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005061 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005062 dumpDispatchStateLocked(dump);
5063
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005064 std::istringstream stream(dump);
5065 std::string line;
5066
5067 while (std::getline(stream, line, '\n')) {
5068 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005069 }
5070}
5071
Prabir Pradhan99987712020-11-10 18:43:05 -08005072std::string InputDispatcher::dumpPointerCaptureStateLocked() {
5073 std::string dump;
5074
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005075 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5076 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005077
5078 std::string windowName = "None";
5079 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005080 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005081 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5082 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5083 : "token has capture without window";
5084 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005085 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005086
5087 return dump;
5088}
5089
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005090void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005091 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5092 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5093 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005094 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005095
Tiger Huang721e26f2018-07-24 22:26:19 +08005096 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5097 dump += StringPrintf(INDENT "FocusedApplications:\n");
5098 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5099 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005100 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005101 const std::chrono::duration timeout =
5102 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005103 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005104 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005105 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005106 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005107 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005108 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005109 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005110
Vishnu Nairc519ff72021-01-21 08:23:08 -08005111 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005112 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005113
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005114 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005115 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005116 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
5117 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005118 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005119 state.displayId, toString(state.down), toString(state.split),
5120 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005121 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005122 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005123 for (size_t i = 0; i < state.windows.size(); i++) {
5124 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005125 dump += StringPrintf(INDENT4
5126 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
5127 i, touchedWindow.windowHandle->getName().c_str(),
5128 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005129 }
5130 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005131 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005132 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005133 }
5134 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005135 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005136 }
5137
arthurhung6d4bed92021-03-17 11:59:33 +08005138 if (mDragState) {
5139 dump += StringPrintf(INDENT "DragState:\n");
5140 mDragState->dump(dump, INDENT2);
5141 }
5142
Arthur Hungb92218b2018-08-14 12:00:21 +08005143 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005144 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5145 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5146 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5147 const auto& displayInfo = it->second;
5148 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5149 displayInfo.logicalHeight);
5150 displayInfo.transform.dump(dump, "transform", INDENT4);
5151 } else {
5152 dump += INDENT2 "No DisplayInfo found!\n";
5153 }
5154
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005155 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005156 dump += INDENT2 "Windows:\n";
5157 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005158 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5159 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005160
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005161 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005162 "paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005163 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005164 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005165 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005166 "applicationInfo.name=%s, "
5167 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005168 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005169 i, windowInfo->name.c_str(), windowInfo->id,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005170 windowInfo->displayId, toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07005171 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005172 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005173 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01005174 windowInfo->flags.string().c_str(),
Dominik Laskowski75788452021-02-09 18:51:25 -08005175 ftl::enum_string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01005176 windowInfo->frameLeft, windowInfo->frameTop,
5177 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005178 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005179 windowInfo->applicationInfo.name.c_str(),
5180 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005181 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01005182 dump += StringPrintf(", inputFeatures=%s",
5183 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005184 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005185 "ms, trustedOverlay=%s, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005186 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005187 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005188 millis(windowInfo->dispatchingTimeout),
5189 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005190 toString(windowInfo->token != nullptr),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005191 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005192 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005193 }
5194 } else {
5195 dump += INDENT2 "Windows: <none>\n";
5196 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005197 }
5198 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005199 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005200 }
5201
Michael Wright3dd60e22019-03-27 22:06:44 +00005202 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005203 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005204 const std::vector<Monitor>& monitors = it.second;
5205 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
5206 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005207 }
5208 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005209 const std::vector<Monitor>& monitors = it.second;
5210 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
5211 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005212 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005213 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00005214 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005215 }
5216
5217 nsecs_t currentTime = now();
5218
5219 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005220 if (!mRecentQueue.empty()) {
5221 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005222 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005223 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005224 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005225 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005226 }
5227 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005228 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005229 }
5230
5231 // Dump event currently being dispatched.
5232 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005233 dump += INDENT "PendingEvent:\n";
5234 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005235 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005236 dump += StringPrintf(", age=%" PRId64 "ms\n",
5237 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005238 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005239 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005240 }
5241
5242 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005243 if (!mInboundQueue.empty()) {
5244 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005245 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005246 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005247 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005248 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005249 }
5250 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005251 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005252 }
5253
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005254 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005255 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005256 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5257 const KeyReplacement& replacement = pair.first;
5258 int32_t newKeyCode = pair.second;
5259 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005260 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005261 }
5262 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005263 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005264 }
5265
Prabir Pradhancef936d2021-07-21 16:17:52 +00005266 if (!mCommandQueue.empty()) {
5267 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5268 } else {
5269 dump += INDENT "CommandQueue: <empty>\n";
5270 }
5271
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005272 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005273 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005274 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005275 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005276 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005277 connection->inputChannel->getFd().get(),
5278 connection->getInputChannelName().c_str(),
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005279 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005280 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005281
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005282 if (!connection->outboundQueue.empty()) {
5283 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5284 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005285 dump += dumpQueue(connection->outboundQueue, currentTime);
5286
Michael Wrightd02c5b62014-02-10 15:10:22 -08005287 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005288 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005289 }
5290
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005291 if (!connection->waitQueue.empty()) {
5292 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5293 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005294 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005295 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005296 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005297 }
5298 }
5299 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005300 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005301 }
5302
5303 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005304 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5305 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005306 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005307 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005308 }
5309
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005310 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005311 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5312 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5313 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005314 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005315 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005316}
5317
Michael Wright3dd60e22019-03-27 22:06:44 +00005318void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5319 const size_t numMonitors = monitors.size();
5320 for (size_t i = 0; i < numMonitors; i++) {
5321 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005322 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005323 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5324 dump += "\n";
5325 }
5326}
5327
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005328class LooperEventCallback : public LooperCallback {
5329public:
5330 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5331 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5332
5333private:
5334 std::function<int(int events)> mCallback;
5335};
5336
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005337Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005338 if (DEBUG_CHANNEL_CREATION) {
5339 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5340 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005341
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005342 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005343 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005344 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005345
5346 if (result) {
5347 return base::Error(result) << "Failed to open input channel pair with name " << name;
5348 }
5349
Michael Wrightd02c5b62014-02-10 15:10:22 -08005350 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005351 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005352 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005353 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005354 sp<Connection> connection =
5355 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005356
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005357 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5358 ALOGE("Created a new connection, but the token %p is already known", token.get());
5359 }
5360 mConnectionsByToken.emplace(token, connection);
5361
5362 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5363 this, std::placeholders::_1, token);
5364
5365 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005366 } // release lock
5367
5368 // Wake the looper because some connections have changed.
5369 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005370 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005371}
5372
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005373Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5374 bool isGestureMonitor,
5375 const std::string& name,
5376 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005377 std::shared_ptr<InputChannel> serverChannel;
5378 std::unique_ptr<InputChannel> clientChannel;
5379 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5380 if (result) {
5381 return base::Error(result) << "Failed to open input channel pair with name " << name;
5382 }
5383
Michael Wright3dd60e22019-03-27 22:06:44 +00005384 { // acquire lock
5385 std::scoped_lock _l(mLock);
5386
5387 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005388 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5389 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005390 }
5391
Garfield Tan15601662020-09-22 15:32:38 -07005392 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005393 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005394 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005395
5396 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5397 ALOGE("Created a new connection, but the token %p is already known", token.get());
5398 }
5399 mConnectionsByToken.emplace(token, connection);
5400 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5401 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005402
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005403 auto& monitorsByDisplay =
5404 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005405 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005406
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005407 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Siarhei Vishniakouc961c742021-05-19 19:16:59 +00005408 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5409 displayId, toString(isGestureMonitor), pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005410 }
Garfield Tan15601662020-09-22 15:32:38 -07005411
Michael Wright3dd60e22019-03-27 22:06:44 +00005412 // Wake the looper because some connections have changed.
5413 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005414 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005415}
5416
Garfield Tan15601662020-09-22 15:32:38 -07005417status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005418 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005419 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005420
Garfield Tan15601662020-09-22 15:32:38 -07005421 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005422 if (status) {
5423 return status;
5424 }
5425 } // release lock
5426
5427 // Wake the poll loop because removing the connection may have changed the current
5428 // synchronization state.
5429 mLooper->wake();
5430 return OK;
5431}
5432
Garfield Tan15601662020-09-22 15:32:38 -07005433status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5434 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005435 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005436 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005437 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005438 return BAD_VALUE;
5439 }
5440
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005441 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005442
Michael Wrightd02c5b62014-02-10 15:10:22 -08005443 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005444 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005445 }
5446
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005447 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005448
5449 nsecs_t currentTime = now();
5450 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5451
5452 connection->status = Connection::STATUS_ZOMBIE;
5453 return OK;
5454}
5455
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005456void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5457 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5458 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005459}
5460
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005461void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005462 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005463 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005464 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005465 std::vector<Monitor>& monitors = it->second;
5466 const size_t numMonitors = monitors.size();
5467 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005468 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005469 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5470 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005471 monitors.erase(monitors.begin() + i);
5472 break;
5473 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005474 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005475 if (monitors.empty()) {
5476 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005477 } else {
5478 ++it;
5479 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005480 }
5481}
5482
Michael Wright3dd60e22019-03-27 22:06:44 +00005483status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5484 { // acquire lock
5485 std::scoped_lock _l(mLock);
5486 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5487
5488 if (!foundDisplayId) {
5489 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5490 return BAD_VALUE;
5491 }
5492 int32_t displayId = foundDisplayId.value();
5493
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005494 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5495 mTouchStatesByDisplay.find(displayId);
5496 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005497 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5498 return BAD_VALUE;
5499 }
5500
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005501 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005502 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005503 std::optional<int32_t> foundDeviceId;
Prabir Pradhan0a99c922021-09-03 08:27:53 -07005504 for (const auto& monitor : state.gestureMonitors) {
5505 if (monitor.inputChannel->getConnectionToken() == token) {
5506 requestingChannel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005507 foundDeviceId = state.deviceId;
5508 }
5509 }
5510 if (!foundDeviceId || !state.down) {
5511 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005512 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005513 return BAD_VALUE;
5514 }
5515 int32_t deviceId = foundDeviceId.value();
5516
5517 // Send cancel events to all the input channels we're stealing from.
5518 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005519 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005520 options.deviceId = deviceId;
5521 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005522 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005523 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005524 std::shared_ptr<InputChannel> channel =
5525 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005526 if (channel != nullptr) {
5527 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005528 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005529 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005530 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005531 canceledWindows += "]";
5532 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5533 canceledWindows.c_str());
5534
Michael Wright3dd60e22019-03-27 22:06:44 +00005535 // Then clear the current touch state so we stop dispatching to them as well.
5536 state.filterNonMonitors();
5537 }
5538 return OK;
5539}
5540
Prabir Pradhan99987712020-11-10 18:43:05 -08005541void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5542 { // acquire lock
5543 std::scoped_lock _l(mLock);
5544 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005545 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005546 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5547 windowHandle != nullptr ? windowHandle->getName().c_str()
5548 : "token without window");
5549 }
5550
Vishnu Nairc519ff72021-01-21 08:23:08 -08005551 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005552 if (focusedToken != windowToken) {
5553 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5554 enabled ? "enable" : "disable");
5555 return;
5556 }
5557
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005558 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08005559 ALOGW("Ignoring request to %s Pointer Capture: "
5560 "window has %s requested pointer capture.",
5561 enabled ? "enable" : "disable", enabled ? "already" : "not");
5562 return;
5563 }
5564
Prabir Pradhan99987712020-11-10 18:43:05 -08005565 setPointerCaptureLocked(enabled);
5566 } // release lock
5567
5568 // Wake the thread to process command entries.
5569 mLooper->wake();
5570}
5571
Michael Wright3dd60e22019-03-27 22:06:44 +00005572std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5573 const sp<IBinder>& token) {
5574 for (const auto& it : mGestureMonitorsByDisplay) {
5575 const std::vector<Monitor>& monitors = it.second;
5576 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005577 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005578 return it.first;
5579 }
5580 }
5581 }
5582 return std::nullopt;
5583}
5584
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005585std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5586 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5587 if (gesturePid.has_value()) {
5588 return gesturePid;
5589 }
5590 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5591}
5592
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005593sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005594 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005595 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005596 }
5597
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005598 for (const auto& [token, connection] : mConnectionsByToken) {
5599 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005600 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005601 }
5602 }
Robert Carr4e670e52018-08-15 13:26:12 -07005603
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005604 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005605}
5606
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005607std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5608 sp<Connection> connection = getConnectionLocked(connectionToken);
5609 if (connection == nullptr) {
5610 return "<nullptr>";
5611 }
5612 return connection->getInputChannelName();
5613}
5614
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005615void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005616 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005617 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005618}
5619
Prabir Pradhancef936d2021-07-21 16:17:52 +00005620void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5621 const sp<Connection>& connection, uint32_t seq,
5622 bool handled, nsecs_t consumeTime) {
5623 // Handle post-event policy actions.
5624 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5625 if (dispatchEntryIt == connection->waitQueue.end()) {
5626 return;
5627 }
5628 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5629 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5630 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5631 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5632 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5633 }
5634 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5635 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5636 connection->inputChannel->getConnectionToken(),
5637 dispatchEntry->deliveryTime, consumeTime, finishTime);
5638 }
5639
5640 bool restartEvent;
5641 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5642 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5643 restartEvent =
5644 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5645 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5646 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5647 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5648 handled);
5649 } else {
5650 restartEvent = false;
5651 }
5652
5653 // Dequeue the event and start the next cycle.
5654 // Because the lock might have been released, it is possible that the
5655 // contents of the wait queue to have been drained, so we need to double-check
5656 // a few things.
5657 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5658 if (dispatchEntryIt != connection->waitQueue.end()) {
5659 dispatchEntry = *dispatchEntryIt;
5660 connection->waitQueue.erase(dispatchEntryIt);
5661 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5662 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5663 if (!connection->responsive) {
5664 connection->responsive = isConnectionResponsive(*connection);
5665 if (connection->responsive) {
5666 // The connection was unresponsive, and now it's responsive.
5667 processConnectionResponsiveLocked(*connection);
5668 }
5669 }
5670 traceWaitQueueLength(*connection);
5671 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
5672 connection->outboundQueue.push_front(dispatchEntry);
5673 traceOutboundQueueLength(*connection);
5674 } else {
5675 releaseDispatchEntry(dispatchEntry);
5676 }
5677 }
5678
5679 // Start the next dispatch cycle for this connection.
5680 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005681}
5682
Prabir Pradhancef936d2021-07-21 16:17:52 +00005683void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5684 const sp<IBinder>& newToken) {
5685 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5686 scoped_unlock unlock(mLock);
5687 mPolicy->notifyFocusChanged(oldToken, newToken);
5688 };
5689 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005690}
5691
Prabir Pradhancef936d2021-07-21 16:17:52 +00005692void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5693 auto command = [this, token, x, y]() REQUIRES(mLock) {
5694 scoped_unlock unlock(mLock);
5695 mPolicy->notifyDropWindow(token, x, y);
5696 };
5697 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005698}
5699
Prabir Pradhancef936d2021-07-21 16:17:52 +00005700void InputDispatcher::sendUntrustedTouchCommandLocked(const std::string& obscuringPackage) {
5701 auto command = [this, obscuringPackage]() REQUIRES(mLock) {
5702 scoped_unlock unlock(mLock);
5703 mPolicy->notifyUntrustedTouch(obscuringPackage);
5704 };
5705 postCommandLocked(std::move(command));
arthurhungf452d0b2021-01-06 00:19:52 +08005706}
5707
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005708void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5709 if (connection == nullptr) {
5710 LOG_ALWAYS_FATAL("Caller must check for nullness");
5711 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005712 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5713 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005714 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005715 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005716 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005717 return;
5718 }
5719 /**
5720 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5721 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5722 * has changed. This could cause newer entries to time out before the already dispatched
5723 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5724 * processes the events linearly. So providing information about the oldest entry seems to be
5725 * most useful.
5726 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005727 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005728 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5729 std::string reason =
5730 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005731 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005732 ns2ms(currentWait),
5733 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005734 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005735 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005736
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005737 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5738
5739 // Stop waking up for events on this connection, it is already unresponsive
5740 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005741}
5742
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005743void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5744 std::string reason =
5745 StringPrintf("%s does not have a focused window", application->getName().c_str());
5746 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005747
Prabir Pradhancef936d2021-07-21 16:17:52 +00005748 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5749 scoped_unlock unlock(mLock);
5750 mPolicy->notifyNoFocusedWindowAnr(application);
5751 };
5752 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005753}
5754
chaviw98318de2021-05-19 16:45:23 -05005755void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005756 const std::string& reason) {
5757 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5758 updateLastAnrStateLocked(windowLabel, reason);
5759}
5760
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005761void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5762 const std::string& reason) {
5763 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005764 updateLastAnrStateLocked(windowLabel, reason);
5765}
5766
5767void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5768 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005769 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005770 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005771 struct tm tm;
5772 localtime_r(&t, &tm);
5773 char timestr[64];
5774 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005775 mLastAnrState.clear();
5776 mLastAnrState += INDENT "ANR:\n";
5777 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005778 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5779 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005780 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005781}
5782
Prabir Pradhancef936d2021-07-21 16:17:52 +00005783void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5784 KeyEntry& entry) {
5785 const KeyEvent event = createKeyEvent(entry);
5786 nsecs_t delay = 0;
5787 { // release lock
5788 scoped_unlock unlock(mLock);
5789 android::base::Timer t;
5790 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5791 entry.policyFlags);
5792 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5793 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5794 std::to_string(t.duration().count()).c_str());
5795 }
5796 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005797
5798 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005799 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005800 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005801 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005802 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005803 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5804 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005805 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005806}
5807
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005808void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005809 auto command = [this, pid, reason = std::move(reason)]() REQUIRES(mLock) {
5810 scoped_unlock unlock(mLock);
5811 mPolicy->notifyMonitorUnresponsive(pid, reason);
5812 };
5813 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005814}
5815
Prabir Pradhancef936d2021-07-21 16:17:52 +00005816void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005817 std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005818 auto command = [this, token, reason = std::move(reason)]() REQUIRES(mLock) {
5819 scoped_unlock unlock(mLock);
5820 mPolicy->notifyWindowUnresponsive(token, reason);
5821 };
5822 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005823}
5824
5825void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005826 auto command = [this, pid]() REQUIRES(mLock) {
5827 scoped_unlock unlock(mLock);
5828 mPolicy->notifyMonitorResponsive(pid);
5829 };
5830 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005831}
5832
Prabir Pradhancef936d2021-07-21 16:17:52 +00005833void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) {
5834 auto command = [this, connectionToken]() REQUIRES(mLock) {
5835 scoped_unlock unlock(mLock);
5836 mPolicy->notifyWindowResponsive(connectionToken);
5837 };
5838 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005839}
5840
5841/**
5842 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5843 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5844 * command entry to the command queue.
5845 */
5846void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5847 std::string reason) {
5848 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5849 if (connection.monitor) {
5850 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5851 reason.c_str());
5852 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5853 if (!pid.has_value()) {
5854 ALOGE("Could not find unresponsive monitor for connection %s",
5855 connection.inputChannel->getName().c_str());
5856 return;
5857 }
5858 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5859 return;
5860 }
5861 // If not a monitor, must be a window
5862 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5863 reason.c_str());
5864 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5865}
5866
5867/**
5868 * Tell the policy that a connection has become responsive so that it can stop ANR.
5869 */
5870void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5871 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5872 if (connection.monitor) {
5873 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5874 if (!pid.has_value()) {
5875 ALOGE("Could not find responsive monitor for connection %s",
5876 connection.inputChannel->getName().c_str());
5877 return;
5878 }
5879 sendMonitorResponsiveCommandLocked(pid.value());
5880 return;
5881 }
5882 // If not a monitor, must be a window
5883 sendWindowResponsiveCommandLocked(connectionToken);
5884}
5885
Prabir Pradhancef936d2021-07-21 16:17:52 +00005886bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005887 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005888 KeyEntry& keyEntry, bool handled) {
5889 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005890 if (!handled) {
5891 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005892 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005893 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005894 return false;
5895 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005896
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005897 // Get the fallback key state.
5898 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005899 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005900 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005901 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005902 connection->inputState.removeFallbackKey(originalKeyCode);
5903 }
5904
5905 if (handled || !dispatchEntry->hasForegroundTarget()) {
5906 // If the application handles the original key for which we previously
5907 // generated a fallback or if the window is not a foreground window,
5908 // then cancel the associated fallback key, if any.
5909 if (fallbackKeyCode != -1) {
5910 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005911 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5912 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
5913 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5914 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
5915 keyEntry.policyFlags);
5916 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005917 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005918 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005919
5920 mLock.unlock();
5921
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005922 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005923 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005924
5925 mLock.lock();
5926
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005927 // Cancel the fallback key.
5928 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005929 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005930 "application handled the original non-fallback key "
5931 "or is no longer a foreground target, "
5932 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005933 options.keyCode = fallbackKeyCode;
5934 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005935 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005936 connection->inputState.removeFallbackKey(originalKeyCode);
5937 }
5938 } else {
5939 // If the application did not handle a non-fallback key, first check
5940 // that we are in a good state to perform unhandled key event processing
5941 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005942 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005943 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005944 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5945 ALOGD("Unhandled key event: Skipping unhandled key event processing "
5946 "since this is not an initial down. "
5947 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5948 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5949 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005950 return false;
5951 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005952
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005953 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005954 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5955 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
5956 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5957 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5958 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005959 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005960
5961 mLock.unlock();
5962
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005963 bool fallback =
5964 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005965 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005966
5967 mLock.lock();
5968
5969 if (connection->status != Connection::STATUS_NORMAL) {
5970 connection->inputState.removeFallbackKey(originalKeyCode);
5971 return false;
5972 }
5973
5974 // Latch the fallback keycode for this key on an initial down.
5975 // The fallback keycode cannot change at any other point in the lifecycle.
5976 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005977 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005978 fallbackKeyCode = event.getKeyCode();
5979 } else {
5980 fallbackKeyCode = AKEYCODE_UNKNOWN;
5981 }
5982 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5983 }
5984
5985 ALOG_ASSERT(fallbackKeyCode != -1);
5986
5987 // Cancel the fallback key if the policy decides not to send it anymore.
5988 // We will continue to dispatch the key to the policy but we will no
5989 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005990 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5991 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005992 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5993 if (fallback) {
5994 ALOGD("Unhandled key event: Policy requested to send key %d"
5995 "as a fallback for %d, but on the DOWN it had requested "
5996 "to send %d instead. Fallback canceled.",
5997 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
5998 } else {
5999 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6000 "but on the DOWN it had requested to send %d. "
6001 "Fallback canceled.",
6002 originalKeyCode, fallbackKeyCode);
6003 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006004 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006005
6006 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
6007 "canceling fallback, policy no longer desires it");
6008 options.keyCode = fallbackKeyCode;
6009 synthesizeCancelationEventsForConnectionLocked(connection, options);
6010
6011 fallback = false;
6012 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006013 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006014 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006015 }
6016 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006017
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006018 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6019 {
6020 std::string msg;
6021 const KeyedVector<int32_t, int32_t>& fallbackKeys =
6022 connection->inputState.getFallbackKeys();
6023 for (size_t i = 0; i < fallbackKeys.size(); i++) {
6024 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
6025 }
6026 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6027 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006028 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006029 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006030
6031 if (fallback) {
6032 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006033 keyEntry.eventTime = event.getEventTime();
6034 keyEntry.deviceId = event.getDeviceId();
6035 keyEntry.source = event.getSource();
6036 keyEntry.displayId = event.getDisplayId();
6037 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
6038 keyEntry.keyCode = fallbackKeyCode;
6039 keyEntry.scanCode = event.getScanCode();
6040 keyEntry.metaState = event.getMetaState();
6041 keyEntry.repeatCount = event.getRepeatCount();
6042 keyEntry.downTime = event.getDownTime();
6043 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006044
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006045 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6046 ALOGD("Unhandled key event: Dispatching fallback key. "
6047 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
6048 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
6049 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006050 return true; // restart the event
6051 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006052 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6053 ALOGD("Unhandled key event: No fallback key.");
6054 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006055
6056 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006057 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006058 }
6059 }
6060 return false;
6061}
6062
Prabir Pradhancef936d2021-07-21 16:17:52 +00006063bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006064 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006065 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006066 return false;
6067}
6068
Michael Wrightd02c5b62014-02-10 15:10:22 -08006069void InputDispatcher::traceInboundQueueLengthLocked() {
6070 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006071 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006072 }
6073}
6074
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006075void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006076 if (ATRACE_ENABLED()) {
6077 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006078 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6079 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006080 }
6081}
6082
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006083void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006084 if (ATRACE_ENABLED()) {
6085 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006086 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6087 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006088 }
6089}
6090
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006091void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006092 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006093
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006094 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006095 dumpDispatchStateLocked(dump);
6096
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006097 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006098 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006099 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006100 }
6101}
6102
6103void InputDispatcher::monitor() {
6104 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006105 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006106 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006107 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006108}
6109
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006110/**
6111 * Wake up the dispatcher and wait until it processes all events and commands.
6112 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6113 * this method can be safely called from any thread, as long as you've ensured that
6114 * the work you are interested in completing has already been queued.
6115 */
6116bool InputDispatcher::waitForIdle() {
6117 /**
6118 * Timeout should represent the longest possible time that a device might spend processing
6119 * events and commands.
6120 */
6121 constexpr std::chrono::duration TIMEOUT = 100ms;
6122 std::unique_lock lock(mLock);
6123 mLooper->wake();
6124 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6125 return result == std::cv_status::no_timeout;
6126}
6127
Vishnu Naire798b472020-07-23 13:52:21 -07006128/**
6129 * Sets focus to the window identified by the token. This must be called
6130 * after updating any input window handles.
6131 *
6132 * Params:
6133 * request.token - input channel token used to identify the window that should gain focus.
6134 * request.focusedToken - the token that the caller expects currently to be focused. If the
6135 * specified token does not match the currently focused window, this request will be dropped.
6136 * If the specified focused token matches the currently focused window, the call will succeed.
6137 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6138 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6139 * when requesting the focus change. This determines which request gets
6140 * precedence if there is a focus change request from another source such as pointer down.
6141 */
Vishnu Nair958da932020-08-21 17:12:37 -07006142void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6143 { // acquire lock
6144 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006145 std::optional<FocusResolver::FocusChanges> changes =
6146 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6147 if (changes) {
6148 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006149 }
6150 } // release lock
6151 // Wake up poll loop since it may need to make new input dispatching choices.
6152 mLooper->wake();
6153}
6154
Vishnu Nairc519ff72021-01-21 08:23:08 -08006155void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6156 if (changes.oldFocus) {
6157 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006158 if (focusedInputChannel) {
6159 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6160 "focus left window");
6161 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006162 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006163 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006164 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006165 if (changes.newFocus) {
6166 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006167 }
6168
Prabir Pradhan99987712020-11-10 18:43:05 -08006169 // If a window has pointer capture, then it must have focus. We need to ensure that this
6170 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6171 // If the window loses focus before it loses pointer capture, then the window can be in a state
6172 // where it has pointer capture but not focus, violating the contract. Therefore we must
6173 // dispatch the pointer capture event before the focus event. Since focus events are added to
6174 // the front of the queue (above), we add the pointer capture event to the front of the queue
6175 // after the focus events are added. This ensures the pointer capture event ends up at the
6176 // front.
6177 disablePointerCaptureForcedLocked();
6178
Vishnu Nairc519ff72021-01-21 08:23:08 -08006179 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006180 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006181 }
6182}
Vishnu Nair958da932020-08-21 17:12:37 -07006183
Prabir Pradhan99987712020-11-10 18:43:05 -08006184void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006185 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006186 return;
6187 }
6188
6189 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6190
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006191 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006192 setPointerCaptureLocked(false);
6193 }
6194
6195 if (!mWindowTokenWithPointerCapture) {
6196 // No need to send capture changes because no window has capture.
6197 return;
6198 }
6199
6200 if (mPendingEvent != nullptr) {
6201 // Move the pending event to the front of the queue. This will give the chance
6202 // for the pending event to be dropped if it is a captured event.
6203 mInboundQueue.push_front(mPendingEvent);
6204 mPendingEvent = nullptr;
6205 }
6206
6207 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006208 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006209 mInboundQueue.push_front(std::move(entry));
6210}
6211
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006212void InputDispatcher::setPointerCaptureLocked(bool enable) {
6213 mCurrentPointerCaptureRequest.enable = enable;
6214 mCurrentPointerCaptureRequest.seq++;
6215 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006216 scoped_unlock unlock(mLock);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006217 mPolicy->setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006218 };
6219 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006220}
6221
Vishnu Nair599f1412021-06-21 10:39:58 -07006222void InputDispatcher::displayRemoved(int32_t displayId) {
6223 { // acquire lock
6224 std::scoped_lock _l(mLock);
6225 // Set an empty list to remove all handles from the specific display.
6226 setInputWindowsLocked(/* window handles */ {}, displayId);
6227 setFocusedApplicationLocked(displayId, nullptr);
6228 // Call focus resolver to clean up stale requests. This must be called after input windows
6229 // have been removed for the removed display.
6230 mFocusResolver.displayRemoved(displayId);
6231 } // release lock
6232
6233 // Wake up poll loop since it may need to make new input dispatching choices.
6234 mLooper->wake();
6235}
6236
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006237void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
6238 const std::vector<DisplayInfo>& displayInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006239 // The listener sends the windows as a flattened array. Separate the windows by display for
6240 // more convenient parsing.
6241 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
chaviw15fab6f2021-06-07 14:15:52 -05006242 for (const auto& info : windowInfos) {
6243 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
6244 handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
6245 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006246
6247 { // acquire lock
6248 std::scoped_lock _l(mLock);
6249 mDisplayInfos.clear();
6250 for (const auto& displayInfo : displayInfos) {
6251 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6252 }
6253
6254 for (const auto& [displayId, handles] : handlesPerDisplay) {
6255 setInputWindowsLocked(handles, displayId);
6256 }
6257 }
6258 // Wake up poll loop since it may need to make new input dispatching choices.
6259 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006260}
6261
Vishnu Nair062a8672021-09-03 16:07:44 -07006262bool InputDispatcher::shouldDropInput(
6263 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
6264 if (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT) ||
6265 (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT_IF_OBSCURED) &&
6266 isWindowObscuredLocked(windowHandle))) {
6267 ALOGW("Dropping %s event targeting %s as requested by input feature %s on display "
6268 "%" PRId32 ".",
6269 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
6270 windowHandle->getInfo()->inputFeatures.string().c_str(),
6271 windowHandle->getInfo()->displayId);
6272 return true;
6273 }
6274 return false;
6275}
6276
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006277void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
6278 const std::vector<gui::WindowInfo>& windowInfos,
6279 const std::vector<DisplayInfo>& displayInfos) {
6280 mDispatcher.onWindowInfosChanged(windowInfos, displayInfos);
6281}
6282
Garfield Tane84e6f92019-08-29 17:28:41 -07006283} // namespace android::inputdispatcher