blob: 22d2e9a97e7431f22a6ffa9919f11caf1249806d [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 +0000413void addGestureMonitors(const std::vector<Monitor>& monitors,
414 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
415 float yOffset = 0) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700416 if (monitors.empty()) {
417 return;
418 }
419 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
420 for (const Monitor& monitor : monitors) {
421 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
422 }
423}
424
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000425status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
426 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700427 std::unique_ptr<InputChannel> uniqueServerChannel;
428 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
429
430 serverChannel = std::move(uniqueServerChannel);
431 return result;
432}
433
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500434template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000435bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500436 if (lhs == nullptr && rhs == nullptr) {
437 return true;
438 }
439 if (lhs == nullptr || rhs == nullptr) {
440 return false;
441 }
442 return *lhs == *rhs;
443}
444
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000445sp<IPlatformCompatNative> getCompatService() {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000446 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
447 if (service == nullptr) {
448 ALOGE("Failed to link to compat service");
449 return nullptr;
450 }
451 return interface_cast<IPlatformCompatNative>(service);
452}
453
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000454KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000455 KeyEvent event;
456 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
457 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
458 entry.repeatCount, entry.downTime, entry.eventTime);
459 return event;
460}
461
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000462std::optional<int32_t> findMonitorPidByToken(
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000463 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
464 const sp<IBinder>& token) {
465 for (const auto& it : monitorsByDisplay) {
466 const std::vector<Monitor>& monitors = it.second;
467 for (const Monitor& monitor : monitors) {
468 if (monitor.inputChannel->getConnectionToken() == token) {
469 return monitor.pid;
470 }
471 }
472 }
473 return std::nullopt;
474}
475
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000476bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000477 // Do not keep track of gesture monitors. They receive every event and would disproportionately
478 // affect the statistics.
479 if (connection.monitor) {
480 return false;
481 }
482 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
483 if (!connection.responsive) {
484 return false;
485 }
486 return true;
487}
488
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000489bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000490 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
491 const int32_t& inputEventId = eventEntry.id;
492 if (inputEventId != dispatchEntry.resolvedEventId) {
493 // Event was transmuted
494 return false;
495 }
496 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
497 return false;
498 }
499 // Only track latency for events that originated from hardware
500 if (eventEntry.isSynthesized()) {
501 return false;
502 }
503 const EventEntry::Type& inputEventEntryType = eventEntry.type;
504 if (inputEventEntryType == EventEntry::Type::KEY) {
505 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
506 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
507 return false;
508 }
509 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
510 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
511 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
512 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
513 return false;
514 }
515 } else {
516 // Not a key or a motion
517 return false;
518 }
519 if (!shouldReportMetricsForConnection(connection)) {
520 return false;
521 }
522 return true;
523}
524
Prabir Pradhancef936d2021-07-21 16:17:52 +0000525/**
526 * Connection is responsive if it has no events in the waitQueue that are older than the
527 * current time.
528 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000529bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000530 const nsecs_t currentTime = now();
531 for (const DispatchEntry* entry : connection.waitQueue) {
532 if (entry->timeoutTime < currentTime) {
533 return false;
534 }
535 }
536 return true;
537}
538
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000539} // namespace
540
Michael Wrightd02c5b62014-02-10 15:10:22 -0800541// --- InputDispatcher ---
542
Garfield Tan00f511d2019-06-12 16:55:40 -0700543InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
544 : mPolicy(policy),
545 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700546 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800547 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700548 mAppSwitchSawKeyDown(false),
549 mAppSwitchDueTime(LONG_LONG_MAX),
550 mNextUnblockedEvent(nullptr),
551 mDispatchEnabled(false),
552 mDispatchFrozen(false),
553 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800554 // mInTouchMode will be initialized by the WindowManager to the default device config.
555 // To avoid leaking stack in case that call never comes, and for tests,
556 // initialize it here anyways.
557 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100558 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000559 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800560 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000561 mLatencyAggregator(),
562 mLatencyTracker(&mLatencyAggregator),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000563 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800564 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800565 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800566
Yi Kong9b14ac62018-07-17 13:48:38 -0700567 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800568
569 policy->getDispatcherConfiguration(&mConfig);
570}
571
572InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000573 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800574
Prabir Pradhancef936d2021-07-21 16:17:52 +0000575 resetKeyRepeatLocked();
576 releasePendingEventLocked();
577 drainInboundQueueLocked();
578 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800579
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000580 while (!mConnectionsByToken.empty()) {
581 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000582 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
583 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800584 }
585}
586
chaviw15fab6f2021-06-07 14:15:52 -0500587void InputDispatcher::onFirstRef() {
588 SurfaceComposerClient::getDefault()->addWindowInfosListener(this);
589}
590
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700591status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700592 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700593 return ALREADY_EXISTS;
594 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700595 mThread = std::make_unique<InputThread>(
596 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
597 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700598}
599
600status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700601 if (mThread && mThread->isCallingThread()) {
602 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700603 return INVALID_OPERATION;
604 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700605 mThread.reset();
606 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700607}
608
Michael Wrightd02c5b62014-02-10 15:10:22 -0800609void InputDispatcher::dispatchOnce() {
610 nsecs_t nextWakeupTime = LONG_LONG_MAX;
611 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800612 std::scoped_lock _l(mLock);
613 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800614
615 // Run a dispatch loop if there are no pending commands.
616 // The dispatch loop might enqueue commands to run afterwards.
617 if (!haveCommandsLocked()) {
618 dispatchOnceInnerLocked(&nextWakeupTime);
619 }
620
621 // Run all pending commands if there are any.
622 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000623 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800624 nextWakeupTime = LONG_LONG_MIN;
625 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800626
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700627 // If we are still waiting for ack on some events,
628 // we might have to wake up earlier to check if an app is anr'ing.
629 const nsecs_t nextAnrCheck = processAnrsLocked();
630 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
631
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800632 // We are about to enter an infinitely long sleep, because we have no commands or
633 // pending or queued events
634 if (nextWakeupTime == LONG_LONG_MAX) {
635 mDispatcherEnteredIdle.notify_all();
636 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800637 } // release lock
638
639 // Wait for callback or timeout or wake. (make sure we round up, not down)
640 nsecs_t currentTime = now();
641 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
642 mLooper->pollOnce(timeoutMillis);
643}
644
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700645/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500646 * Raise ANR if there is no focused window.
647 * Before the ANR is raised, do a final state check:
648 * 1. The currently focused application must be the same one we are waiting for.
649 * 2. Ensure we still don't have a focused window.
650 */
651void InputDispatcher::processNoFocusedWindowAnrLocked() {
652 // Check if the application that we are waiting for is still focused.
653 std::shared_ptr<InputApplicationHandle> focusedApplication =
654 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
655 if (focusedApplication == nullptr ||
656 focusedApplication->getApplicationToken() !=
657 mAwaitedFocusedApplication->getApplicationToken()) {
658 // Unexpected because we should have reset the ANR timer when focused application changed
659 ALOGE("Waited for a focused window, but focused application has already changed to %s",
660 focusedApplication->getName().c_str());
661 return; // The focused application has changed.
662 }
663
chaviw98318de2021-05-19 16:45:23 -0500664 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500665 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
666 if (focusedWindowHandle != nullptr) {
667 return; // We now have a focused window. No need for ANR.
668 }
669 onAnrLocked(mAwaitedFocusedApplication);
670}
671
672/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700673 * Check if any of the connections' wait queues have events that are too old.
674 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
675 * Return the time at which we should wake up next.
676 */
677nsecs_t InputDispatcher::processAnrsLocked() {
678 const nsecs_t currentTime = now();
679 nsecs_t nextAnrCheck = LONG_LONG_MAX;
680 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
681 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
682 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500683 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700684 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500685 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700686 return LONG_LONG_MIN;
687 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500688 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700689 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
690 }
691 }
692
693 // Check if any connection ANRs are due
694 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
695 if (currentTime < nextAnrCheck) { // most likely scenario
696 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
697 }
698
699 // If we reached here, we have an unresponsive connection.
700 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
701 if (connection == nullptr) {
702 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
703 return nextAnrCheck;
704 }
705 connection->responsive = false;
706 // Stop waking up for this unresponsive connection
707 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000708 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700709 return LONG_LONG_MIN;
710}
711
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500712std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
chaviw98318de2021-05-19 16:45:23 -0500713 sp<WindowInfoHandle> window = getWindowHandleLocked(token);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700714 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500715 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700716 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500717 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700718}
719
Michael Wrightd02c5b62014-02-10 15:10:22 -0800720void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
721 nsecs_t currentTime = now();
722
Jeff Browndc5992e2014-04-11 01:27:26 -0700723 // Reset the key repeat timer whenever normal dispatch is suspended while the
724 // device is in a non-interactive state. This is to ensure that we abort a key
725 // repeat if the device is just coming out of sleep.
726 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800727 resetKeyRepeatLocked();
728 }
729
730 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
731 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100732 if (DEBUG_FOCUS) {
733 ALOGD("Dispatch frozen. Waiting some more.");
734 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800735 return;
736 }
737
738 // Optimize latency of app switches.
739 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
740 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
741 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
742 if (mAppSwitchDueTime < *nextWakeupTime) {
743 *nextWakeupTime = mAppSwitchDueTime;
744 }
745
746 // Ready to start a new event.
747 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700748 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700749 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800750 if (isAppSwitchDue) {
751 // The inbound queue is empty so the app switch key we were waiting
752 // for will never arrive. Stop waiting for it.
753 resetPendingAppSwitchLocked(false);
754 isAppSwitchDue = false;
755 }
756
757 // Synthesize a key repeat if appropriate.
758 if (mKeyRepeatState.lastKeyEntry) {
759 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
760 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
761 } else {
762 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
763 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
764 }
765 }
766 }
767
768 // Nothing to do if there is no pending event.
769 if (!mPendingEvent) {
770 return;
771 }
772 } else {
773 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700774 mPendingEvent = mInboundQueue.front();
775 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800776 traceInboundQueueLengthLocked();
777 }
778
779 // Poke user activity for this event.
780 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700781 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800782 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800783 }
784
785 // Now we have an event to dispatch.
786 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700787 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800788 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700789 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800790 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700791 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800792 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700793 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800794 }
795
796 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700797 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800798 }
799
800 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700801 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700802 const ConfigurationChangedEntry& typedEntry =
803 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700804 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700805 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700806 break;
807 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800808
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700809 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700810 const DeviceResetEntry& typedEntry =
811 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700812 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700813 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700814 break;
815 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800816
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100817 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700818 std::shared_ptr<FocusEntry> typedEntry =
819 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100820 dispatchFocusLocked(currentTime, typedEntry);
821 done = true;
822 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
823 break;
824 }
825
Antonio Kantek7242d8b2021-08-05 16:07:20 -0700826 case EventEntry::Type::TOUCH_MODE_CHANGED: {
827 const auto typedEntry = std::static_pointer_cast<TouchModeEntry>(mPendingEvent);
828 dispatchTouchModeChangeLocked(currentTime, typedEntry);
829 done = true;
830 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
831 break;
832 }
833
Prabir Pradhan99987712020-11-10 18:43:05 -0800834 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
835 const auto typedEntry =
836 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
837 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
838 done = true;
839 break;
840 }
841
arthurhungb89ccb02020-12-30 16:19:01 +0800842 case EventEntry::Type::DRAG: {
843 std::shared_ptr<DragEntry> typedEntry =
844 std::static_pointer_cast<DragEntry>(mPendingEvent);
845 dispatchDragLocked(currentTime, typedEntry);
846 done = true;
847 break;
848 }
849
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700850 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700851 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700852 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700853 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700854 resetPendingAppSwitchLocked(true);
855 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700856 } else if (dropReason == DropReason::NOT_DROPPED) {
857 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700858 }
859 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700860 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700861 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700862 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700863 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
864 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700865 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700866 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700867 break;
868 }
869
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700870 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700871 std::shared_ptr<MotionEntry> motionEntry =
872 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700873 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
874 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800875 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700876 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700877 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700878 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700879 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
880 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700881 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700882 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700883 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800884 }
Chris Yef59a2f42020-10-16 12:55:26 -0700885
886 case EventEntry::Type::SENSOR: {
887 std::shared_ptr<SensorEntry> sensorEntry =
888 std::static_pointer_cast<SensorEntry>(mPendingEvent);
889 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
890 dropReason = DropReason::APP_SWITCH;
891 }
892 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
893 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
894 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
895 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
896 dropReason = DropReason::STALE;
897 }
898 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
899 done = true;
900 break;
901 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800902 }
903
904 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700905 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700906 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800907 }
Michael Wright3a981722015-06-10 15:26:13 +0100908 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800909
910 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700911 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800912 }
913}
914
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700915/**
916 * Return true if the events preceding this incoming motion event should be dropped
917 * Return false otherwise (the default behaviour)
918 */
919bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700920 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700921 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700922
923 // Optimize case where the current application is unresponsive and the user
924 // decides to touch a window in a different application.
925 // If the application takes too long to catch up then we drop all events preceding
926 // the touch into the other window.
927 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700928 int32_t displayId = motionEntry.displayId;
929 int32_t x = static_cast<int32_t>(
930 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
931 int32_t y = static_cast<int32_t>(
932 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
chaviw98318de2021-05-19 16:45:23 -0500933 sp<WindowInfoHandle> touchedWindowHandle =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700934 findTouchedWindowAtLocked(displayId, x, y, nullptr);
935 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700936 touchedWindowHandle->getApplicationToken() !=
937 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700938 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700939 ALOGI("Pruning input queue because user touched a different application while waiting "
940 "for %s",
941 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700942 return true;
943 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700944
945 // Alternatively, maybe there's a gesture monitor that could handle this event
Siarhei Vishniakou64452932020-11-06 17:51:32 -0600946 std::vector<TouchedMonitor> gestureMonitors = findTouchedGestureMonitorsLocked(displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700947 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
948 sp<Connection> connection =
949 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000950 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700951 // This monitor could take more input. Drop all events preceding this
952 // event, so that gesture monitor could get a chance to receive the stream
953 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
954 "responsive gesture monitor that may handle the event",
955 mAwaitedFocusedApplication->getName().c_str());
956 return true;
957 }
958 }
959 }
960
961 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
962 // yet been processed by some connections, the dispatcher will wait for these motion
963 // events to be processed before dispatching the key event. This is because these motion events
964 // may cause a new window to be launched, which the user might expect to receive focus.
965 // To prevent waiting forever for such events, just send the key to the currently focused window
966 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
967 ALOGD("Received a new pointer down event, stop waiting for events to process and "
968 "just send the pending key event to the focused window.");
969 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700970 }
971 return false;
972}
973
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700974bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700975 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700976 mInboundQueue.push_back(std::move(newEntry));
977 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800978 traceInboundQueueLengthLocked();
979
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700980 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700981 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700982 // Optimize app switch latency.
983 // If the application takes too long to catch up then we drop all events preceding
984 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700985 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700986 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700987 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700988 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700989 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700990 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000991 if (DEBUG_APP_SWITCH) {
992 ALOGD("App switch is pending!");
993 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700994 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700995 mAppSwitchSawKeyDown = false;
996 needWake = true;
997 }
998 }
999 }
1000 break;
1001 }
1002
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001003 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001004 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
1005 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001006 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001007 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001008 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001009 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001010 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001011 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1012 break;
1013 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001014 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001015 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001016 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001017 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001018 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1019 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001020 // nothing to do
1021 break;
1022 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001023 }
1024
1025 return needWake;
1026}
1027
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001028void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001029 // Do not store sensor event in recent queue to avoid flooding the queue.
1030 if (entry->type != EventEntry::Type::SENSOR) {
1031 mRecentQueue.push_back(entry);
1032 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001033 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001034 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001035 }
1036}
1037
chaviw98318de2021-05-19 16:45:23 -05001038sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1039 int32_t y, TouchState* touchState,
1040 bool addOutsideTargets,
1041 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001042 if (addOutsideTargets && touchState == nullptr) {
1043 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001044 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001045 // Traverse windows from front to back to find touched window.
chaviw98318de2021-05-19 16:45:23 -05001046 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
1047 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001048 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001049 continue;
1050 }
chaviw98318de2021-05-19 16:45:23 -05001051 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001052 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +01001053 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001054
1055 if (windowInfo->visible) {
chaviw98318de2021-05-19 16:45:23 -05001056 if (!flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
1057 bool isTouchModal = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
1058 !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001059 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
1060 // Found window.
1061 return windowHandle;
1062 }
1063 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001064
chaviw98318de2021-05-19 16:45:23 -05001065 if (addOutsideTargets && flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001066 touchState->addOrUpdateWindow(windowHandle,
1067 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1068 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001069 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001070 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001071 }
1072 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001073 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001074}
1075
Garfield Tane84e6f92019-08-29 17:28:41 -07001076std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001077 int32_t displayId) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00001078 std::vector<TouchedMonitor> touchedMonitors;
1079
1080 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
1081 addGestureMonitors(monitors, touchedMonitors);
Michael Wright3dd60e22019-03-27 22:06:44 +00001082 return touchedMonitors;
1083}
1084
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001085void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001086 const char* reason;
1087 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001088 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001089 if (DEBUG_INBOUND_EVENT_DETAILS) {
1090 ALOGD("Dropped event because policy consumed it.");
1091 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001092 reason = "inbound event was dropped because the policy consumed it";
1093 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001094 case DropReason::DISABLED:
1095 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001096 ALOGI("Dropped event because input dispatch is disabled.");
1097 }
1098 reason = "inbound event was dropped because input dispatch is disabled";
1099 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001100 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001101 ALOGI("Dropped event because of pending overdue app switch.");
1102 reason = "inbound event was dropped because of pending overdue app switch";
1103 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001104 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001105 ALOGI("Dropped event because the current application is not responding and the user "
1106 "has started interacting with a different application.");
1107 reason = "inbound event was dropped because the current application is not responding "
1108 "and the user has started interacting with a different application";
1109 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001110 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001111 ALOGI("Dropped event because it is stale.");
1112 reason = "inbound event was dropped because it is stale";
1113 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001114 case DropReason::NO_POINTER_CAPTURE:
1115 ALOGI("Dropped event because there is no window with Pointer Capture.");
1116 reason = "inbound event was dropped because there is no window with Pointer Capture";
1117 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001118 case DropReason::NOT_DROPPED: {
1119 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001120 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001121 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001122 }
1123
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001124 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001125 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001126 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1127 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001128 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001129 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001130 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001131 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1132 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001133 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1134 synthesizeCancelationEventsForAllConnectionsLocked(options);
1135 } else {
1136 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1137 synthesizeCancelationEventsForAllConnectionsLocked(options);
1138 }
1139 break;
1140 }
Chris Yef59a2f42020-10-16 12:55:26 -07001141 case EventEntry::Type::SENSOR: {
1142 break;
1143 }
arthurhungb89ccb02020-12-30 16:19:01 +08001144 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1145 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001146 break;
1147 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001148 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001149 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001150 case EventEntry::Type::CONFIGURATION_CHANGED:
1151 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001152 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001153 break;
1154 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001155 }
1156}
1157
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001158static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001159 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1160 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001161}
1162
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001163bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1164 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1165 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1166 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001167}
1168
1169bool InputDispatcher::isAppSwitchPendingLocked() {
1170 return mAppSwitchDueTime != LONG_LONG_MAX;
1171}
1172
1173void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1174 mAppSwitchDueTime = LONG_LONG_MAX;
1175
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001176 if (DEBUG_APP_SWITCH) {
1177 if (handled) {
1178 ALOGD("App switch has arrived.");
1179 } else {
1180 ALOGD("App switch was abandoned.");
1181 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001182 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001183}
1184
Michael Wrightd02c5b62014-02-10 15:10:22 -08001185bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001186 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001187}
1188
Prabir Pradhancef936d2021-07-21 16:17:52 +00001189bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001190 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001191 return false;
1192 }
1193
1194 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001195 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001196 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001197 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1198 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001199 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001200 return true;
1201}
1202
Prabir Pradhancef936d2021-07-21 16:17:52 +00001203void InputDispatcher::postCommandLocked(Command&& command) {
1204 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001205}
1206
1207void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001208 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001209 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001210 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001211 releaseInboundEventLocked(entry);
1212 }
1213 traceInboundQueueLengthLocked();
1214}
1215
1216void InputDispatcher::releasePendingEventLocked() {
1217 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001218 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001219 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001220 }
1221}
1222
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001223void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001224 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001225 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001226 if (DEBUG_DISPATCH_CYCLE) {
1227 ALOGD("Injected inbound event was dropped.");
1228 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001229 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001230 }
1231 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001232 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001233 }
1234 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001235}
1236
1237void InputDispatcher::resetKeyRepeatLocked() {
1238 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001239 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001240 }
1241}
1242
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001243std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1244 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001245
Michael Wright2e732952014-09-24 13:26:59 -07001246 uint32_t policyFlags = entry->policyFlags &
1247 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001248
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001249 std::shared_ptr<KeyEntry> newEntry =
1250 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1251 entry->source, entry->displayId, policyFlags, entry->action,
1252 entry->flags, entry->keyCode, entry->scanCode,
1253 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001254
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001255 newEntry->syntheticRepeat = true;
1256 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001257 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001258 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001259}
1260
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001261bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001262 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001263 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1264 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1265 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001266
1267 // Reset key repeating in case a keyboard device was added or removed or something.
1268 resetKeyRepeatLocked();
1269
1270 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001271 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1272 scoped_unlock unlock(mLock);
1273 mPolicy->notifyConfigurationChanged(eventTime);
1274 };
1275 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001276 return true;
1277}
1278
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001279bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1280 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001281 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1282 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1283 entry.deviceId);
1284 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001285
liushenxiang42232912021-05-21 20:24:09 +08001286 // Reset key repeating in case a keyboard device was disabled or enabled.
1287 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1288 resetKeyRepeatLocked();
1289 }
1290
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001291 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001292 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001293 synthesizeCancelationEventsForAllConnectionsLocked(options);
1294 return true;
1295}
1296
Vishnu Nairad321cd2020-08-20 16:40:21 -07001297void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001298 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001299 if (mPendingEvent != nullptr) {
1300 // Move the pending event to the front of the queue. This will give the chance
1301 // for the pending event to get dispatched to the newly focused window
1302 mInboundQueue.push_front(mPendingEvent);
1303 mPendingEvent = nullptr;
1304 }
1305
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001306 std::unique_ptr<FocusEntry> focusEntry =
1307 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1308 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001309
1310 // This event should go to the front of the queue, but behind all other focus events
1311 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001312 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001313 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001314 [](const std::shared_ptr<EventEntry>& event) {
1315 return event->type == EventEntry::Type::FOCUS;
1316 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001317
1318 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001319 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001320}
1321
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001322void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001323 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001324 if (channel == nullptr) {
1325 return; // Window has gone away
1326 }
1327 InputTarget target;
1328 target.inputChannel = channel;
1329 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1330 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001331 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1332 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001333 std::string reason = std::string("reason=").append(entry->reason);
1334 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001335 dispatchEventLocked(currentTime, entry, {target});
1336}
1337
Prabir Pradhan99987712020-11-10 18:43:05 -08001338void InputDispatcher::dispatchPointerCaptureChangedLocked(
1339 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1340 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001341 dropReason = DropReason::NOT_DROPPED;
1342
Prabir Pradhan99987712020-11-10 18:43:05 -08001343 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001344 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001345
1346 if (entry->pointerCaptureRequest.enable) {
1347 // Enable Pointer Capture.
1348 if (haveWindowWithPointerCapture &&
1349 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1350 LOG_ALWAYS_FATAL("This request to enable Pointer Capture has already been dispatched "
1351 "to the window.");
1352 }
1353 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001354 // This can happen if a window requests capture and immediately releases capture.
1355 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001356 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001357 return;
1358 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001359 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1360 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1361 return;
1362 }
1363
Vishnu Nairc519ff72021-01-21 08:23:08 -08001364 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001365 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1366 mWindowTokenWithPointerCapture = token;
1367 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001368 // Disable Pointer Capture.
1369 // We do not check if the sequence number matches for requests to disable Pointer Capture
1370 // for two reasons:
1371 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1372 // to disable capture with the same sequence number: one generated by
1373 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1374 // Capture being disabled in InputReader.
1375 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1376 // actual Pointer Capture state that affects events being generated by input devices is
1377 // in InputReader.
1378 if (!haveWindowWithPointerCapture) {
1379 // Pointer capture was already forcefully disabled because of focus change.
1380 dropReason = DropReason::NOT_DROPPED;
1381 return;
1382 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001383 token = mWindowTokenWithPointerCapture;
1384 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001385 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001386 setPointerCaptureLocked(false);
1387 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001388 }
1389
1390 auto channel = getInputChannelLocked(token);
1391 if (channel == nullptr) {
1392 // Window has gone away, clean up Pointer Capture state.
1393 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001394 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001395 setPointerCaptureLocked(false);
1396 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001397 return;
1398 }
1399 InputTarget target;
1400 target.inputChannel = channel;
1401 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1402 entry->dispatchInProgress = true;
1403 dispatchEventLocked(currentTime, entry, {target});
1404
1405 dropReason = DropReason::NOT_DROPPED;
1406}
1407
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001408void InputDispatcher::dispatchTouchModeChangeLocked(nsecs_t currentTime,
1409 const std::shared_ptr<TouchModeEntry>& entry) {
1410 const std::vector<sp<WindowInfoHandle>>& windowHandles =
1411 getWindowHandlesLocked(mFocusedDisplayId);
1412 if (windowHandles.empty()) {
1413 return;
1414 }
1415 const std::vector<InputTarget> inputTargets =
1416 getInputTargetsFromWindowHandlesLocked(windowHandles);
1417 if (inputTargets.empty()) {
1418 return;
1419 }
1420 entry->dispatchInProgress = true;
1421 dispatchEventLocked(currentTime, entry, inputTargets);
1422}
1423
1424std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1425 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1426 std::vector<InputTarget> inputTargets;
1427 for (const sp<WindowInfoHandle>& handle : windowHandles) {
1428 // TODO(b/193718270): Due to performance concerns, consider notifying visible windows only.
1429 const sp<IBinder>& token = handle->getToken();
1430 if (token == nullptr) {
1431 continue;
1432 }
1433 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1434 if (channel == nullptr) {
1435 continue; // Window has gone away
1436 }
1437 InputTarget target;
1438 target.inputChannel = channel;
1439 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1440 inputTargets.push_back(target);
1441 }
1442 return inputTargets;
1443}
1444
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001445bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001446 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001447 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001448 if (!entry->dispatchInProgress) {
1449 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1450 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1451 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1452 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001453 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001454 // We have seen two identical key downs in a row which indicates that the device
1455 // driver is automatically generating key repeats itself. We take note of the
1456 // repeat here, but we disable our own next key repeat timer since it is clear that
1457 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001458 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1459 // Make sure we don't get key down from a different device. If a different
1460 // device Id has same key pressed down, the new device Id will replace the
1461 // current one to hold the key repeat with repeat count reset.
1462 // In the future when got a KEY_UP on the device id, drop it and do not
1463 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001464 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1465 resetKeyRepeatLocked();
1466 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1467 } else {
1468 // Not a repeat. Save key down state in case we do see a repeat later.
1469 resetKeyRepeatLocked();
1470 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1471 }
1472 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001473 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1474 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001475 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001476 if (DEBUG_INBOUND_EVENT_DETAILS) {
1477 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1478 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001479 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001480 resetKeyRepeatLocked();
1481 }
1482
1483 if (entry->repeatCount == 1) {
1484 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1485 } else {
1486 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1487 }
1488
1489 entry->dispatchInProgress = true;
1490
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001491 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001492 }
1493
1494 // Handle case where the policy asked us to try again later last time.
1495 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1496 if (currentTime < entry->interceptKeyWakeupTime) {
1497 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1498 *nextWakeupTime = entry->interceptKeyWakeupTime;
1499 }
1500 return false; // wait until next wakeup
1501 }
1502 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1503 entry->interceptKeyWakeupTime = 0;
1504 }
1505
1506 // Give the policy a chance to intercept the key.
1507 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1508 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001509 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001510 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001511
1512 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1513 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1514 };
1515 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001516 return false; // wait for the command to run
1517 } else {
1518 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1519 }
1520 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001521 if (*dropReason == DropReason::NOT_DROPPED) {
1522 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001523 }
1524 }
1525
1526 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001527 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001528 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001529 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1530 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001531 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001532 return true;
1533 }
1534
1535 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001536 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001537 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001538 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001539 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001540 return false;
1541 }
1542
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001543 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001544 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001545 return true;
1546 }
1547
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001548 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001549 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001550
1551 // Dispatch the key.
1552 dispatchEventLocked(currentTime, entry, inputTargets);
1553 return true;
1554}
1555
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001556void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001557 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1558 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1559 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1560 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1561 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1562 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1563 entry.metaState, entry.repeatCount, entry.downTime);
1564 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001565}
1566
Prabir Pradhancef936d2021-07-21 16:17:52 +00001567void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1568 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001569 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001570 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1571 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1572 "source=0x%x, sensorType=%s",
1573 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001574 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001575 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001576 auto command = [this, entry]() REQUIRES(mLock) {
1577 scoped_unlock unlock(mLock);
1578
1579 if (entry->accuracyChanged) {
1580 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1581 }
1582 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1583 entry->hwTimestamp, entry->values);
1584 };
1585 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001586}
1587
1588bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001589 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1590 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001591 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001592 }
Chris Yef59a2f42020-10-16 12:55:26 -07001593 { // acquire lock
1594 std::scoped_lock _l(mLock);
1595
1596 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1597 std::shared_ptr<EventEntry> entry = *it;
1598 if (entry->type == EventEntry::Type::SENSOR) {
1599 it = mInboundQueue.erase(it);
1600 releaseInboundEventLocked(entry);
1601 }
1602 }
1603 }
1604 return true;
1605}
1606
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001607bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001608 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001609 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001610 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001611 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001612 entry->dispatchInProgress = true;
1613
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001614 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001615 }
1616
1617 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001618 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001619 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001620 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1621 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001622 return true;
1623 }
1624
1625 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1626
1627 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001628 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001629
1630 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001631 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001632 if (isPointerEvent) {
1633 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001634 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001635 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001636 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001637 } else {
1638 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001639 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001640 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001641 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001642 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001643 return false;
1644 }
1645
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001646 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001647 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001648 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1649 return true;
1650 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001651 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001652 CancelationOptions::Mode mode(isPointerEvent
1653 ? CancelationOptions::CANCEL_POINTER_EVENTS
1654 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1655 CancelationOptions options(mode, "input event injection failed");
1656 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001657 return true;
1658 }
1659
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001660 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001661 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001662
1663 // Dispatch the motion.
1664 if (conflictingPointerActions) {
1665 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001666 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001667 synthesizeCancelationEventsForAllConnectionsLocked(options);
1668 }
1669 dispatchEventLocked(currentTime, entry, inputTargets);
1670 return true;
1671}
1672
chaviw98318de2021-05-19 16:45:23 -05001673void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001674 bool isExiting, const MotionEntry& motionEntry) {
1675 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1676 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1677 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1678 PointerCoords pointerCoords;
1679 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1680 pointerCoords.transform(windowHandle->getInfo()->transform);
1681
1682 std::unique_ptr<DragEntry> dragEntry =
1683 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1684 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1685 pointerCoords.getY());
1686
1687 enqueueInboundEventLocked(std::move(dragEntry));
1688}
1689
1690void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1691 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1692 if (channel == nullptr) {
1693 return; // Window has gone away
1694 }
1695 InputTarget target;
1696 target.inputChannel = channel;
1697 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1698 entry->dispatchInProgress = true;
1699 dispatchEventLocked(currentTime, entry, {target});
1700}
1701
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001702void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001703 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1704 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1705 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001706 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001707 "metaState=0x%x, buttonState=0x%x,"
1708 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1709 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001710 entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
1711 entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.edgeFlags,
1712 entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001713
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001714 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1715 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1716 "x=%f, y=%f, pressure=%f, size=%f, "
1717 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1718 "orientation=%f",
1719 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1720 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1721 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1722 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1723 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1724 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1725 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1726 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1727 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1728 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1729 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001730 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001731}
1732
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001733void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1734 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001735 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001736 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001737 if (DEBUG_DISPATCH_CYCLE) {
1738 ALOGD("dispatchEventToCurrentInputTargets");
1739 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001740
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001741 updateInteractionTokensLocked(*eventEntry, inputTargets);
1742
Michael Wrightd02c5b62014-02-10 15:10:22 -08001743 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1744
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001745 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001746
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001747 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001748 sp<Connection> connection =
1749 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001750 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001751 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001752 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001753 if (DEBUG_FOCUS) {
1754 ALOGD("Dropping event delivery to target with channel '%s' because it "
1755 "is no longer registered with the input dispatcher.",
1756 inputTarget.inputChannel->getName().c_str());
1757 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001758 }
1759 }
1760}
1761
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001762void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1763 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1764 // If the policy decides to close the app, we will get a channel removal event via
1765 // unregisterInputChannel, and will clean up the connection that way. We are already not
1766 // sending new pointers to the connection when it blocked, but focused events will continue to
1767 // pile up.
1768 ALOGW("Canceling events for %s because it is unresponsive",
1769 connection->inputChannel->getName().c_str());
1770 if (connection->status == Connection::STATUS_NORMAL) {
1771 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1772 "application not responding");
1773 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001774 }
1775}
1776
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001777void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001778 if (DEBUG_FOCUS) {
1779 ALOGD("Resetting ANR timeouts.");
1780 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001781
1782 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001783 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001784 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001785}
1786
Tiger Huang721e26f2018-07-24 22:26:19 +08001787/**
1788 * Get the display id that the given event should go to. If this event specifies a valid display id,
1789 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1790 * Focused display is the display that the user most recently interacted with.
1791 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001792int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001793 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001794 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001795 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001796 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1797 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001798 break;
1799 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001800 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001801 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1802 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001803 break;
1804 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001805 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001806 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001807 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001808 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001809 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001810 case EventEntry::Type::SENSOR:
1811 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001812 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001813 return ADISPLAY_ID_NONE;
1814 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001815 }
1816 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1817}
1818
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001819bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1820 const char* focusedWindowName) {
1821 if (mAnrTracker.empty()) {
1822 // already processed all events that we waited for
1823 mKeyIsWaitingForEventsTimeout = std::nullopt;
1824 return false;
1825 }
1826
1827 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1828 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001829 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001830 mKeyIsWaitingForEventsTimeout = currentTime +
1831 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1832 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001833 return true;
1834 }
1835
1836 // We still have pending events, and already started the timer
1837 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1838 return true; // Still waiting
1839 }
1840
1841 // Waited too long, and some connection still hasn't processed all motions
1842 // Just send the key to the focused window
1843 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1844 focusedWindowName);
1845 mKeyIsWaitingForEventsTimeout = std::nullopt;
1846 return false;
1847}
1848
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001849InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1850 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1851 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001852 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001853
Tiger Huang721e26f2018-07-24 22:26:19 +08001854 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001855 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001856 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001857 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1858
Michael Wrightd02c5b62014-02-10 15:10:22 -08001859 // If there is no currently focused window and no focused application
1860 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001861 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1862 ALOGI("Dropping %s event because there is no focused window or focused application in "
1863 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08001864 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001865 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001866 }
1867
Vishnu Nair062a8672021-09-03 16:07:44 -07001868 // Drop key events if requested by input feature
1869 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
1870 return InputEventInjectionResult::FAILED;
1871 }
1872
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001873 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1874 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1875 // start interacting with another application via touch (app switch). This code can be removed
1876 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1877 // an app is expected to have a focused window.
1878 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1879 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1880 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001881 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1882 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1883 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001884 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001885 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001886 ALOGW("Waiting because no window has focus but %s may eventually add a "
1887 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001888 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001889 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001890 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001891 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1892 // Already raised ANR. Drop the event
1893 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08001894 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001895 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001896 } else {
1897 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001898 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001899 }
1900 }
1901
1902 // we have a valid, non-null focused window
1903 resetNoFocusedWindowTimeoutLocked();
1904
Michael Wrightd02c5b62014-02-10 15:10:22 -08001905 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001906 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001907 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001908 }
1909
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001910 if (focusedWindowHandle->getInfo()->paused) {
1911 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001912 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001913 }
1914
1915 // If the event is a key event, then we must wait for all previous events to
1916 // complete before delivering it because previous events may have the
1917 // side-effect of transferring focus to a different window and we want to
1918 // ensure that the following keys are sent to the new window.
1919 //
1920 // Suppose the user touches a button in a window then immediately presses "A".
1921 // If the button causes a pop-up window to appear then we want to ensure that
1922 // the "A" key is delivered to the new pop-up window. This is because users
1923 // often anticipate pending UI changes when typing on a keyboard.
1924 // To obtain this behavior, we must serialize key events with respect to all
1925 // prior input events.
1926 if (entry.type == EventEntry::Type::KEY) {
1927 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1928 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001929 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001930 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001931 }
1932
1933 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001934 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001935 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1936 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001937
1938 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001939 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001940}
1941
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001942/**
1943 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1944 * that are currently unresponsive.
1945 */
1946std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1947 const std::vector<TouchedMonitor>& monitors) const {
1948 std::vector<TouchedMonitor> responsiveMonitors;
1949 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1950 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1951 sp<Connection> connection = getConnectionLocked(
1952 monitor.monitor.inputChannel->getConnectionToken());
1953 if (connection == nullptr) {
1954 ALOGE("Could not find connection for monitor %s",
1955 monitor.monitor.inputChannel->getName().c_str());
1956 return false;
1957 }
1958 if (!connection->responsive) {
1959 ALOGW("Unresponsive monitor %s will not get the new gesture",
1960 connection->inputChannel->getName().c_str());
1961 return false;
1962 }
1963 return true;
1964 });
1965 return responsiveMonitors;
1966}
1967
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001968InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1969 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1970 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001971 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001972 enum InjectionPermission {
1973 INJECTION_PERMISSION_UNKNOWN,
1974 INJECTION_PERMISSION_GRANTED,
1975 INJECTION_PERMISSION_DENIED
1976 };
1977
Michael Wrightd02c5b62014-02-10 15:10:22 -08001978 // For security reasons, we defer updating the touch state until we are sure that
1979 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001980 int32_t displayId = entry.displayId;
1981 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001982 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1983
1984 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001985 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001986 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05001987 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1988 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001989
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001990 // Copy current touch state into tempTouchState.
1991 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1992 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001993 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001994 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001995 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1996 mTouchStatesByDisplay.find(displayId);
1997 if (oldStateIt != mTouchStatesByDisplay.end()) {
1998 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001999 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08002000 }
2001
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002002 bool isSplit = tempTouchState.split;
2003 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
2004 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
2005 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002006 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2007 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2008 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
2009 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2010 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002011 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002012 bool wrongDevice = false;
2013 if (newGesture) {
2014 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002015 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002016 ALOGI("Dropping event because a pointer for a different device is already down "
2017 "in display %" PRId32,
2018 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002019 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002020 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002021 switchedDevice = false;
2022 wrongDevice = true;
2023 goto Failed;
2024 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002025 tempTouchState.reset();
2026 tempTouchState.down = down;
2027 tempTouchState.deviceId = entry.deviceId;
2028 tempTouchState.source = entry.source;
2029 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002030 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002031 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002032 ALOGI("Dropping move event because a pointer for a different device is already active "
2033 "in display %" PRId32,
2034 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002035 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002036 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002037 switchedDevice = false;
2038 wrongDevice = true;
2039 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002040 }
2041
2042 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2043 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2044
Garfield Tan00f511d2019-06-12 16:55:40 -07002045 int32_t x;
2046 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002047 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07002048 // Always dispatch mouse events to cursor position.
2049 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002050 x = int32_t(entry.xCursorPosition);
2051 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07002052 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002053 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
2054 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07002055 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002056 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002057 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
2058 isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00002059
2060 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002061 ? findTouchedGestureMonitorsLocked(displayId)
Michael Wright3dd60e22019-03-27 22:06:44 +00002062 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002063
Michael Wrightd02c5b62014-02-10 15:10:22 -08002064 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002065 if (newTouchedWindowHandle != nullptr &&
2066 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07002067 // New window supports splitting, but we should never split mouse events.
2068 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002069 } else if (isSplit) {
2070 // New window does not support splitting but we have already split events.
2071 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002072 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002073 }
2074
2075 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002076 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002077 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002078 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002079 }
2080
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002081 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
2082 ALOGI("Not sending touch event to %s because it is paused",
2083 newTouchedWindowHandle->getName().c_str());
2084 newTouchedWindowHandle = nullptr;
2085 }
2086
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002087 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002088 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002089 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
2090 if (!isResponsive) {
2091 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002092 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
2093 newTouchedWindowHandle = nullptr;
2094 }
2095 }
2096
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002097 // Drop events that can't be trusted due to occlusion
2098 if (newTouchedWindowHandle != nullptr &&
2099 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2100 TouchOcclusionInfo occlusionInfo =
2101 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002102 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002103 if (DEBUG_TOUCH_OCCLUSION) {
2104 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2105 for (const auto& log : occlusionInfo.debugInfo) {
2106 ALOGD("%s", log.c_str());
2107 }
2108 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00002109 sendUntrustedTouchCommandLocked(occlusionInfo.obscuringPackage);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002110 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2111 ALOGW("Dropping untrusted touch event due to %s/%d",
2112 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2113 newTouchedWindowHandle = nullptr;
2114 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002115 }
2116 }
2117
Vishnu Nair062a8672021-09-03 16:07:44 -07002118 // Drop touch events if requested by input feature
2119 if (newTouchedWindowHandle != nullptr && shouldDropInput(entry, newTouchedWindowHandle)) {
2120 newTouchedWindowHandle = nullptr;
2121 }
2122
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002123 // Also don't send the new touch event to unresponsive gesture monitors
2124 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
2125
Michael Wright3dd60e22019-03-27 22:06:44 +00002126 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
2127 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002128 "(%d, %d) in display %" PRId32 ".",
2129 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002130 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00002131 goto Failed;
2132 }
2133
2134 if (newTouchedWindowHandle != nullptr) {
2135 // Set target flags.
2136 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
2137 if (isSplit) {
2138 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002139 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002140 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2141 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2142 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2143 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2144 }
2145
2146 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07002147 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2148 newHoverWindowHandle = nullptr;
2149 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002150 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002151 }
2152
2153 // Update the temporary touch state.
2154 BitSet32 pointerIds;
2155 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002156 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002157 pointerIds.markBit(pointerId);
2158 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002159 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002160 }
2161
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002162 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002163 } else {
2164 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2165
2166 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002167 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002168 if (DEBUG_FOCUS) {
2169 ALOGD("Dropping event because the pointer is not down or we previously "
2170 "dropped the pointer down event in display %" PRId32,
2171 displayId);
2172 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002173 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002174 goto Failed;
2175 }
2176
arthurhung6d4bed92021-03-17 11:59:33 +08002177 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002178
Michael Wrightd02c5b62014-02-10 15:10:22 -08002179 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002180 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002181 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002182 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2183 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002184
chaviw98318de2021-05-19 16:45:23 -05002185 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002186 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002187 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Vishnu Nair062a8672021-09-03 16:07:44 -07002188
2189 // Drop touch events if requested by input feature
2190 if (newTouchedWindowHandle != nullptr &&
2191 shouldDropInput(entry, newTouchedWindowHandle)) {
2192 newTouchedWindowHandle = nullptr;
2193 }
2194
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002195 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2196 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002197 if (DEBUG_FOCUS) {
2198 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2199 oldTouchedWindowHandle->getName().c_str(),
2200 newTouchedWindowHandle->getName().c_str(), displayId);
2201 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002202 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002203 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2204 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2205 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002206
2207 // Make a slippery entrance into the new window.
2208 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2209 isSplit = true;
2210 }
2211
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002212 int32_t targetFlags =
2213 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002214 if (isSplit) {
2215 targetFlags |= InputTarget::FLAG_SPLIT;
2216 }
2217 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2218 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002219 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2220 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002221 }
2222
2223 BitSet32 pointerIds;
2224 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002225 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002226 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002227 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002228 }
2229 }
2230 }
2231
2232 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002233 // Let the previous window know that the hover sequence is over, unless we already did it
2234 // when dispatching it as is to newTouchedWindowHandle.
2235 if (mLastHoverWindowHandle != nullptr &&
2236 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2237 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002238 if (DEBUG_HOVER) {
2239 ALOGD("Sending hover exit event to window %s.",
2240 mLastHoverWindowHandle->getName().c_str());
2241 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002242 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2243 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002244 }
2245
Garfield Tandf26e862020-07-01 20:18:19 -07002246 // Let the new window know that the hover sequence is starting, unless we already did it
2247 // when dispatching it as is to newTouchedWindowHandle.
2248 if (newHoverWindowHandle != nullptr &&
2249 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2250 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002251 if (DEBUG_HOVER) {
2252 ALOGD("Sending hover enter event to window %s.",
2253 newHoverWindowHandle->getName().c_str());
2254 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002255 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2256 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2257 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002258 }
2259 }
2260
2261 // Check permission to inject into all touched foreground windows and ensure there
2262 // is at least one touched foreground window.
2263 {
2264 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002265 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002266 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2267 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002268 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002269 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002270 injectionPermission = INJECTION_PERMISSION_DENIED;
2271 goto Failed;
2272 }
2273 }
2274 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002275 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002276 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002277 ALOGI("Dropping event because there is no touched foreground window in display "
2278 "%" PRId32 " or gesture monitor to receive it.",
2279 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002280 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002281 goto Failed;
2282 }
2283
2284 // Permission granted to injection into all touched foreground windows.
2285 injectionPermission = INJECTION_PERMISSION_GRANTED;
2286 }
2287
2288 // Check whether windows listening for outside touches are owned by the same UID. If it is
2289 // set the policy flag that we will not reveal coordinate information to this window.
2290 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002291 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002292 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002293 if (foregroundWindowHandle) {
2294 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002295 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002296 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002297 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2298 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2299 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002300 InputTarget::FLAG_ZERO_COORDS,
2301 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002302 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002303 }
2304 }
2305 }
2306 }
2307
Michael Wrightd02c5b62014-02-10 15:10:22 -08002308 // If this is the first pointer going down and the touched window has a wallpaper
2309 // then also add the touched wallpaper windows so they are locked in for the duration
2310 // of the touch gesture.
2311 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2312 // engine only supports touch events. We would need to add a mechanism similar
2313 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2314 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002315 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002316 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002317 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
chaviw98318de2021-05-19 16:45:23 -05002318 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002319 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002320 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2321 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002322 if (info->displayId == displayId &&
chaviw98318de2021-05-19 16:45:23 -05002323 windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002324 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002325 .addOrUpdateWindow(windowHandle,
2326 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2327 InputTarget::
2328 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2329 InputTarget::FLAG_DISPATCH_AS_IS,
2330 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002331 }
2332 }
2333 }
2334 }
2335
2336 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002337 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002338
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002339 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002340 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002341 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002342 }
2343
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002344 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002345 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002346 touchedMonitor.yOffset, displayId, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002347 }
2348
Michael Wrightd02c5b62014-02-10 15:10:22 -08002349 // Drop the outside or hover touch windows since we will not care about them
2350 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002351 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002352
2353Failed:
2354 // Check injection permission once and for all.
2355 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002356 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002357 injectionPermission = INJECTION_PERMISSION_GRANTED;
2358 } else {
2359 injectionPermission = INJECTION_PERMISSION_DENIED;
2360 }
2361 }
2362
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002363 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2364 return injectionResult;
2365 }
2366
Michael Wrightd02c5b62014-02-10 15:10:22 -08002367 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002368 if (!wrongDevice) {
2369 if (switchedDevice) {
2370 if (DEBUG_FOCUS) {
2371 ALOGD("Conflicting pointer actions: Switched to a different device.");
2372 }
2373 *outConflictingPointerActions = true;
2374 }
2375
2376 if (isHoverAction) {
2377 // Started hovering, therefore no longer down.
2378 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002379 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002380 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2381 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002382 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002383 *outConflictingPointerActions = true;
2384 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002385 tempTouchState.reset();
2386 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2387 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2388 tempTouchState.deviceId = entry.deviceId;
2389 tempTouchState.source = entry.source;
2390 tempTouchState.displayId = displayId;
2391 }
2392 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2393 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2394 // All pointers up or canceled.
2395 tempTouchState.reset();
2396 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2397 // First pointer went down.
2398 if (oldState && oldState->down) {
2399 if (DEBUG_FOCUS) {
2400 ALOGD("Conflicting pointer actions: Down received while already down.");
2401 }
2402 *outConflictingPointerActions = true;
2403 }
2404 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2405 // One pointer went up.
2406 if (isSplit) {
2407 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2408 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002409
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002410 for (size_t i = 0; i < tempTouchState.windows.size();) {
2411 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2412 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2413 touchedWindow.pointerIds.clearBit(pointerId);
2414 if (touchedWindow.pointerIds.isEmpty()) {
2415 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2416 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002417 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002418 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002419 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002420 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002421 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002422 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002423
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002424 // Save changes unless the action was scroll in which case the temporary touch
2425 // state was only valid for this one action.
2426 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2427 if (tempTouchState.displayId >= 0) {
2428 mTouchStatesByDisplay[displayId] = tempTouchState;
2429 } else {
2430 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002431 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002432 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002433
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002434 // Update hover state.
2435 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002436 }
2437
Michael Wrightd02c5b62014-02-10 15:10:22 -08002438 return injectionResult;
2439}
2440
arthurhung6d4bed92021-03-17 11:59:33 +08002441void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
chaviw98318de2021-05-19 16:45:23 -05002442 const sp<WindowInfoHandle> dropWindow =
arthurhung6d4bed92021-03-17 11:59:33 +08002443 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002444 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002445 if (dropWindow) {
2446 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002447 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002448 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002449 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002450 }
2451 mDragState.reset();
2452}
2453
2454void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2455 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002456 return;
2457 }
2458
arthurhung6d4bed92021-03-17 11:59:33 +08002459 if (!mDragState->isStartDrag) {
2460 mDragState->isStartDrag = true;
2461 mDragState->isStylusButtonDownAtStart =
2462 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2463 }
2464
arthurhungb89ccb02020-12-30 16:19:01 +08002465 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2466 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2467 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2468 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002469 // Handle the special case : stylus button no longer pressed.
2470 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2471 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2472 finishDragAndDrop(entry.displayId, x, y);
2473 return;
2474 }
2475
chaviw98318de2021-05-19 16:45:23 -05002476 const sp<WindowInfoHandle> hoverWindowHandle =
arthurhung6d4bed92021-03-17 11:59:33 +08002477 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002478 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002479 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002480 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2481 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2482 if (mDragState->dragHoverWindowHandle != nullptr) {
2483 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2484 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002485 }
arthurhung6d4bed92021-03-17 11:59:33 +08002486 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002487 }
2488 // enqueue drag location if needed.
2489 if (hoverWindowHandle != nullptr) {
2490 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2491 }
arthurhung6d4bed92021-03-17 11:59:33 +08002492 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2493 finishDragAndDrop(entry.displayId, x, y);
2494 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002495 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002496 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002497 }
2498}
2499
chaviw98318de2021-05-19 16:45:23 -05002500void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002501 int32_t targetFlags, BitSet32 pointerIds,
2502 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002503 std::vector<InputTarget>::iterator it =
2504 std::find_if(inputTargets.begin(), inputTargets.end(),
2505 [&windowHandle](const InputTarget& inputTarget) {
2506 return inputTarget.inputChannel->getConnectionToken() ==
2507 windowHandle->getToken();
2508 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002509
chaviw98318de2021-05-19 16:45:23 -05002510 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002511
2512 if (it == inputTargets.end()) {
2513 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002514 std::shared_ptr<InputChannel> inputChannel =
2515 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002516 if (inputChannel == nullptr) {
2517 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2518 return;
2519 }
2520 inputTarget.inputChannel = inputChannel;
2521 inputTarget.flags = targetFlags;
2522 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002523 const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
2524 if (displayInfoIt != mDisplayInfos.end()) {
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002525 inputTarget.displayTransform = displayInfoIt->second.transform;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002526 } else {
2527 ALOGI_IF(isPerWindowInputRotationEnabled(),
2528 "DisplayInfo not found for window on display: %d", windowInfo->displayId);
2529 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002530 inputTargets.push_back(inputTarget);
2531 it = inputTargets.end() - 1;
2532 }
2533
2534 ALOG_ASSERT(it->flags == targetFlags);
2535 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2536
chaviw1ff3d1e2020-07-01 15:53:47 -07002537 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002538}
2539
Michael Wright3dd60e22019-03-27 22:06:44 +00002540void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002541 int32_t displayId, float xOffset,
2542 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002543 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2544 mGlobalMonitorsByDisplay.find(displayId);
2545
2546 if (it != mGlobalMonitorsByDisplay.end()) {
2547 const std::vector<Monitor>& monitors = it->second;
2548 for (const Monitor& monitor : monitors) {
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002549 addMonitoringTargetLocked(monitor, xOffset, yOffset, displayId, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002550 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002551 }
2552}
2553
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002554void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002555 float yOffset, int32_t displayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002556 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002557 InputTarget target;
2558 target.inputChannel = monitor.inputChannel;
2559 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002560 ui::Transform t = ui::Transform(xOffset, yOffset);
2561 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
2562 // Input monitors always get un-rotated display coordinates. We undo the display
2563 // rotation that is present in the display transform so that display rotation is not
2564 // applied to these input targets.
2565 const auto& displayInfo = it->second;
2566 int32_t width = displayInfo.logicalWidth;
2567 int32_t height = displayInfo.logicalHeight;
2568 const auto orientation = displayInfo.transform.getOrientation();
2569 uint32_t inverseOrientation = orientation;
2570 if (orientation == ui::Transform::ROT_90) {
2571 inverseOrientation = ui::Transform::ROT_270;
2572 std::swap(width, height);
2573 } else if (orientation == ui::Transform::ROT_270) {
2574 inverseOrientation = ui::Transform::ROT_90;
2575 std::swap(width, height);
2576 }
2577 target.displayTransform =
2578 ui::Transform(inverseOrientation, width, height) * displayInfo.transform;
2579 t = t * target.displayTransform;
2580 }
chaviw1ff3d1e2020-07-01 15:53:47 -07002581 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002582 inputTargets.push_back(target);
2583}
2584
chaviw98318de2021-05-19 16:45:23 -05002585bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002586 const InjectionState* injectionState) {
2587 if (injectionState &&
2588 (windowHandle == nullptr ||
2589 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2590 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002591 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002592 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002593 "owned by uid %d",
2594 injectionState->injectorPid, injectionState->injectorUid,
2595 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002596 } else {
2597 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002598 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002599 }
2600 return false;
2601 }
2602 return true;
2603}
2604
Robert Carrc9bf1d32020-04-13 17:21:08 -07002605/**
2606 * Indicate whether one window handle should be considered as obscuring
2607 * another window handle. We only check a few preconditions. Actually
2608 * checking the bounds is left to the caller.
2609 */
chaviw98318de2021-05-19 16:45:23 -05002610static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2611 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002612 // Compare by token so cloned layers aren't counted
2613 if (haveSameToken(windowHandle, otherHandle)) {
2614 return false;
2615 }
2616 auto info = windowHandle->getInfo();
2617 auto otherInfo = otherHandle->getInfo();
2618 if (!otherInfo->visible) {
2619 return false;
chaviw98318de2021-05-19 16:45:23 -05002620 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002621 // Those act as if they were invisible, so we don't need to flag them.
2622 // We do want to potentially flag touchable windows even if they have 0
2623 // opacity, since they can consume touches and alter the effects of the
2624 // user interaction (eg. apps that rely on
2625 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2626 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2627 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002628 } else if (info->ownerUid == otherInfo->ownerUid) {
2629 // If ownerUid is the same we don't generate occlusion events as there
2630 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002631 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002632 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002633 return false;
2634 } else if (otherInfo->displayId != info->displayId) {
2635 return false;
2636 }
2637 return true;
2638}
2639
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002640/**
2641 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2642 * untrusted, one should check:
2643 *
2644 * 1. If result.hasBlockingOcclusion is true.
2645 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2646 * BLOCK_UNTRUSTED.
2647 *
2648 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2649 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2650 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2651 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2652 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2653 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2654 *
2655 * If neither of those is true, then it means the touch can be allowed.
2656 */
2657InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002658 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2659 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002660 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002661 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002662 TouchOcclusionInfo info;
2663 info.hasBlockingOcclusion = false;
2664 info.obscuringOpacity = 0;
2665 info.obscuringUid = -1;
2666 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002667 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002668 if (windowHandle == otherHandle) {
2669 break; // All future windows are below us. Exit early.
2670 }
chaviw98318de2021-05-19 16:45:23 -05002671 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002672 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2673 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002674 if (DEBUG_TOUCH_OCCLUSION) {
2675 info.debugInfo.push_back(
2676 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2677 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002678 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2679 // we perform the checks below to see if the touch can be propagated or not based on the
2680 // window's touch occlusion mode
2681 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2682 info.hasBlockingOcclusion = true;
2683 info.obscuringUid = otherInfo->ownerUid;
2684 info.obscuringPackage = otherInfo->packageName;
2685 break;
2686 }
2687 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2688 uint32_t uid = otherInfo->ownerUid;
2689 float opacity =
2690 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2691 // Given windows A and B:
2692 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2693 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2694 opacityByUid[uid] = opacity;
2695 if (opacity > info.obscuringOpacity) {
2696 info.obscuringOpacity = opacity;
2697 info.obscuringUid = uid;
2698 info.obscuringPackage = otherInfo->packageName;
2699 }
2700 }
2701 }
2702 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002703 if (DEBUG_TOUCH_OCCLUSION) {
2704 info.debugInfo.push_back(
2705 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2706 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002707 return info;
2708}
2709
chaviw98318de2021-05-19 16:45:23 -05002710std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002711 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002712 return StringPrintf(INDENT2
2713 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2714 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2715 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2716 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Dominik Laskowski75788452021-02-09 18:51:25 -08002717 isTouchedWindow ? "[TOUCHED] " : "", ftl::enum_string(info->type).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002718 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002719 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2720 info->frameTop, info->frameRight, info->frameBottom,
2721 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002722 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2723 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2724 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002725}
2726
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002727bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2728 if (occlusionInfo.hasBlockingOcclusion) {
2729 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2730 occlusionInfo.obscuringUid);
2731 return false;
2732 }
2733 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2734 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2735 "%.2f, maximum allowed = %.2f)",
2736 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2737 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2738 return false;
2739 }
2740 return true;
2741}
2742
chaviw98318de2021-05-19 16:45:23 -05002743bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002744 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002745 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002746 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2747 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002748 if (windowHandle == otherHandle) {
2749 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002750 }
chaviw98318de2021-05-19 16:45:23 -05002751 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002752 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002753 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002754 return true;
2755 }
2756 }
2757 return false;
2758}
2759
chaviw98318de2021-05-19 16:45:23 -05002760bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002761 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002762 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2763 const WindowInfo* windowInfo = windowHandle->getInfo();
2764 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002765 if (windowHandle == otherHandle) {
2766 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002767 }
chaviw98318de2021-05-19 16:45:23 -05002768 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002769 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002770 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002771 return true;
2772 }
2773 }
2774 return false;
2775}
2776
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002777std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002778 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002779 if (applicationHandle != nullptr) {
2780 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002781 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002782 } else {
2783 return applicationHandle->getName();
2784 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002785 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002786 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002787 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002788 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002789 }
2790}
2791
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002792void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002793 if (eventEntry.type == EventEntry::Type::FOCUS ||
arthurhungb89ccb02020-12-30 16:19:01 +08002794 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED ||
2795 eventEntry.type == EventEntry::Type::DRAG) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002796 // Focus or pointer capture changed events are passed to apps, but do not represent user
2797 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002798 return;
2799 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002800 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002801 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002802 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002803 const WindowInfo* info = focusedWindowHandle->getInfo();
2804 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002805 if (DEBUG_DISPATCH_CYCLE) {
2806 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2807 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002808 return;
2809 }
2810 }
2811
2812 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002813 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002814 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002815 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2816 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002817 return;
2818 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002819
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002820 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002821 eventType = USER_ACTIVITY_EVENT_TOUCH;
2822 }
2823 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002824 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002825 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002826 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2827 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002828 return;
2829 }
2830 eventType = USER_ACTIVITY_EVENT_BUTTON;
2831 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002832 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07002833 case EventEntry::Type::TOUCH_MODE_CHANGED: {
2834 break;
2835 }
2836
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002837 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002838 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002839 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002840 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08002841 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2842 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002843 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08002844 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002845 break;
2846 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002847 }
2848
Prabir Pradhancef936d2021-07-21 16:17:52 +00002849 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2850 REQUIRES(mLock) {
2851 scoped_unlock unlock(mLock);
2852 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2853 };
2854 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002855}
2856
2857void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002858 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002859 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002860 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002861 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002862 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002863 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002864 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002865 ATRACE_NAME(message.c_str());
2866 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002867 if (DEBUG_DISPATCH_CYCLE) {
2868 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2869 "globalScaleFactor=%f, pointerIds=0x%x %s",
2870 connection->getInputChannelName().c_str(), inputTarget.flags,
2871 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2872 inputTarget.getPointerInfoString().c_str());
2873 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002874
2875 // Skip this event if the connection status is not normal.
2876 // We don't want to enqueue additional outbound events if the connection is broken.
2877 if (connection->status != Connection::STATUS_NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002878 if (DEBUG_DISPATCH_CYCLE) {
2879 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
2880 connection->getInputChannelName().c_str(), connection->getStatusLabel());
2881 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002882 return;
2883 }
2884
2885 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002886 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2887 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2888 "Entry type %s should not have FLAG_SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08002889 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002890
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002891 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002892 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002893 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002894 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002895 if (!splitMotionEntry) {
2896 return; // split event was dropped
2897 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002898 if (DEBUG_FOCUS) {
2899 ALOGD("channel '%s' ~ Split motion event.",
2900 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002901 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002902 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002903 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2904 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002905 return;
2906 }
2907 }
2908
2909 // Not splitting. Enqueue dispatch entries for the event as is.
2910 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2911}
2912
2913void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002914 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002915 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002916 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002917 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002918 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002919 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002920 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002921 ATRACE_NAME(message.c_str());
2922 }
2923
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002924 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002925
2926 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002927 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002928 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002929 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002930 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002931 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002932 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002933 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002934 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002935 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002936 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002937 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002938 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002939
2940 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002941 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002942 startDispatchCycleLocked(currentTime, connection);
2943 }
2944}
2945
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002946void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002947 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002948 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002949 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002950 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002951 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2952 connection->getInputChannelName().c_str(),
2953 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002954 ATRACE_NAME(message.c_str());
2955 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002956 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002957 if (!(inputTargetFlags & dispatchMode)) {
2958 return;
2959 }
2960 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2961
2962 // This is a new event.
2963 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002964 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002965 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002966
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002967 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2968 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002969 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002970 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002971 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002972 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002973 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002974 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002975 dispatchEntry->resolvedAction = keyEntry.action;
2976 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002977
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002978 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2979 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002980 if (DEBUG_DISPATCH_CYCLE) {
2981 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
2982 "event",
2983 connection->getInputChannelName().c_str());
2984 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002985 return; // skip the inconsistent event
2986 }
2987 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002988 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002989
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002990 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002991 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002992 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2993 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2994 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2995 static_cast<int32_t>(IdGenerator::Source::OTHER);
2996 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002997 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2998 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2999 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
3000 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
3001 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
3002 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3003 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
3004 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
3005 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
3006 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
3007 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003008 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003009 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003010 }
3011 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003012 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3013 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003014 if (DEBUG_DISPATCH_CYCLE) {
3015 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
3016 "enter event",
3017 connection->getInputChannelName().c_str());
3018 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003019 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
3020 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003021 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3022 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003023
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003024 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003025 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
3026 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3027 }
3028 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
3029 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3030 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003031
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003032 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
3033 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003034 if (DEBUG_DISPATCH_CYCLE) {
3035 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
3036 "event",
3037 connection->getInputChannelName().c_str());
3038 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003039 return; // skip the inconsistent event
3040 }
3041
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003042 dispatchEntry->resolvedEventId =
3043 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
3044 ? mIdGenerator.nextId()
3045 : motionEntry.id;
3046 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
3047 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3048 ") to MotionEvent(id=0x%" PRIx32 ").",
3049 motionEntry.id, dispatchEntry->resolvedEventId);
3050 ATRACE_NAME(message.c_str());
3051 }
3052
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003053 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3054 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
3055 // Skip reporting pointer down outside focus to the policy.
3056 break;
3057 }
3058
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003059 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003060 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003061
3062 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003063 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003064 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003065 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003066 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3067 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003068 break;
3069 }
Chris Yef59a2f42020-10-16 12:55:26 -07003070 case EventEntry::Type::SENSOR: {
3071 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3072 break;
3073 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003074 case EventEntry::Type::CONFIGURATION_CHANGED:
3075 case EventEntry::Type::DEVICE_RESET: {
3076 LOG_ALWAYS_FATAL("%s events should not go to apps",
Dominik Laskowski75788452021-02-09 18:51:25 -08003077 ftl::enum_string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003078 break;
3079 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003080 }
3081
3082 // Remember that we are waiting for this dispatch to complete.
3083 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003084 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003085 }
3086
3087 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003088 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003089 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003090}
3091
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003092/**
3093 * This function is purely for debugging. It helps us understand where the user interaction
3094 * was taking place. For example, if user is touching launcher, we will see a log that user
3095 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3096 * We will see both launcher and wallpaper in that list.
3097 * Once the interaction with a particular set of connections starts, no new logs will be printed
3098 * until the set of interacted connections changes.
3099 *
3100 * The following items are skipped, to reduce the logspam:
3101 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3102 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3103 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3104 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3105 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003106 */
3107void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3108 const std::vector<InputTarget>& targets) {
3109 // Skip ACTION_UP events, and all events other than keys and motions
3110 if (entry.type == EventEntry::Type::KEY) {
3111 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3112 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3113 return;
3114 }
3115 } else if (entry.type == EventEntry::Type::MOTION) {
3116 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3117 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3118 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3119 return;
3120 }
3121 } else {
3122 return; // Not a key or a motion
3123 }
3124
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003125 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003126 std::vector<sp<Connection>> newConnections;
3127 for (const InputTarget& target : targets) {
3128 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3129 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3130 continue; // Skip windows that receive ACTION_OUTSIDE
3131 }
3132
3133 sp<IBinder> token = target.inputChannel->getConnectionToken();
3134 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003135 if (connection == nullptr) {
3136 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003137 }
3138 newConnectionTokens.insert(std::move(token));
3139 newConnections.emplace_back(connection);
3140 }
3141 if (newConnectionTokens == mInteractionConnectionTokens) {
3142 return; // no change
3143 }
3144 mInteractionConnectionTokens = newConnectionTokens;
3145
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003146 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003147 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003148 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003149 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003150 std::string message = "Interaction with: " + targetList;
3151 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003152 message += "<none>";
3153 }
3154 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3155}
3156
chaviwfd6d3512019-03-25 13:23:49 -07003157void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003158 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003159 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003160 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3161 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003162 return;
3163 }
3164
Vishnu Nairc519ff72021-01-21 08:23:08 -08003165 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003166 if (focusedToken == token) {
3167 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003168 return;
3169 }
3170
Prabir Pradhancef936d2021-07-21 16:17:52 +00003171 auto command = [this, token]() REQUIRES(mLock) {
3172 scoped_unlock unlock(mLock);
3173 mPolicy->onPointerDownOutsideFocus(token);
3174 };
3175 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003176}
3177
3178void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003179 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003180 if (ATRACE_ENABLED()) {
3181 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003182 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003183 ATRACE_NAME(message.c_str());
3184 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003185 if (DEBUG_DISPATCH_CYCLE) {
3186 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3187 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003188
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003189 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3190 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003191 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003192 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003193 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003194 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003195
3196 // Publish the event.
3197 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003198 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3199 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003200 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003201 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3202 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003203
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003204 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003205 status = connection->inputPublisher
3206 .publishKeyEvent(dispatchEntry->seq,
3207 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3208 keyEntry.source, keyEntry.displayId,
3209 std::move(hmac), dispatchEntry->resolvedAction,
3210 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3211 keyEntry.scanCode, keyEntry.metaState,
3212 keyEntry.repeatCount, keyEntry.downTime,
3213 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003214 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003215 }
3216
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003217 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003218 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003219
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003220 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003221 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003222
chaviw82357092020-01-28 13:13:06 -08003223 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003224 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003225 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3226 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003227 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003228 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3229 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003230 // Don't apply window scale here since we don't want scale to affect raw
3231 // coordinates. The scale will be sent back to the client and applied
3232 // later when requesting relative coordinates.
3233 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3234 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003235 }
3236 usingCoords = scaledCoords;
3237 }
3238 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003239 // We don't want the dispatch target to know.
3240 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003241 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003242 scaledCoords[i].clear();
3243 }
3244 usingCoords = scaledCoords;
3245 }
3246 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003247
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003248 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003249
3250 // Publish the motion event.
3251 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003252 .publishMotionEvent(dispatchEntry->seq,
3253 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003254 motionEntry.deviceId, motionEntry.source,
3255 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003256 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003257 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003258 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003259 motionEntry.edgeFlags, motionEntry.metaState,
3260 motionEntry.buttonState,
3261 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003262 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003263 motionEntry.xPrecision, motionEntry.yPrecision,
3264 motionEntry.xCursorPosition,
3265 motionEntry.yCursorPosition,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003266 dispatchEntry->rawTransform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003267 motionEntry.downTime, motionEntry.eventTime,
3268 motionEntry.pointerCount,
3269 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003270 break;
3271 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003272
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003273 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003274 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003275 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003276 focusEntry.id,
3277 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003278 mInTouchMode);
3279 break;
3280 }
3281
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003282 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3283 const TouchModeEntry& touchModeEntry =
3284 static_cast<const TouchModeEntry&>(eventEntry);
3285 status = connection->inputPublisher
3286 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3287 touchModeEntry.inTouchMode);
3288
3289 break;
3290 }
3291
Prabir Pradhan99987712020-11-10 18:43:05 -08003292 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3293 const auto& captureEntry =
3294 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3295 status = connection->inputPublisher
3296 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003297 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003298 break;
3299 }
3300
arthurhungb89ccb02020-12-30 16:19:01 +08003301 case EventEntry::Type::DRAG: {
3302 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3303 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3304 dragEntry.id, dragEntry.x,
3305 dragEntry.y,
3306 dragEntry.isExiting);
3307 break;
3308 }
3309
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003310 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003311 case EventEntry::Type::DEVICE_RESET:
3312 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003313 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003314 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003315 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003316 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003317 }
3318
3319 // Check the result.
3320 if (status) {
3321 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003322 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003323 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003324 "This is unexpected because the wait queue is empty, so the pipe "
3325 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003326 "event to it, status=%s(%d)",
3327 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3328 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003329 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3330 } else {
3331 // Pipe is full and we are waiting for the app to finish process some events
3332 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003333 if (DEBUG_DISPATCH_CYCLE) {
3334 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3335 "waiting for the application to catch up",
3336 connection->getInputChannelName().c_str());
3337 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003338 }
3339 } else {
3340 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003341 "status=%s(%d)",
3342 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3343 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003344 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3345 }
3346 return;
3347 }
3348
3349 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003350 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3351 connection->outboundQueue.end(),
3352 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003353 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003354 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003355 if (connection->responsive) {
3356 mAnrTracker.insert(dispatchEntry->timeoutTime,
3357 connection->inputChannel->getConnectionToken());
3358 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003359 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003360 }
3361}
3362
chaviw09c8d2d2020-08-24 15:48:26 -07003363std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3364 size_t size;
3365 switch (event.type) {
3366 case VerifiedInputEvent::Type::KEY: {
3367 size = sizeof(VerifiedKeyEvent);
3368 break;
3369 }
3370 case VerifiedInputEvent::Type::MOTION: {
3371 size = sizeof(VerifiedMotionEvent);
3372 break;
3373 }
3374 }
3375 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3376 return mHmacKeyManager.sign(start, size);
3377}
3378
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003379const std::array<uint8_t, 32> InputDispatcher::getSignature(
3380 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3381 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3382 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3383 // Only sign events up and down events as the purely move events
3384 // are tied to their up/down counterparts so signing would be redundant.
3385 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3386 verifiedEvent.actionMasked = actionMasked;
3387 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003388 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003389 }
3390 return INVALID_HMAC;
3391}
3392
3393const std::array<uint8_t, 32> InputDispatcher::getSignature(
3394 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3395 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3396 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3397 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003398 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003399}
3400
Michael Wrightd02c5b62014-02-10 15:10:22 -08003401void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003402 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003403 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003404 if (DEBUG_DISPATCH_CYCLE) {
3405 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3406 connection->getInputChannelName().c_str(), seq, toString(handled));
3407 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003408
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003409 if (connection->status == Connection::STATUS_BROKEN ||
3410 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003411 return;
3412 }
3413
3414 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003415 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3416 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3417 };
3418 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003419}
3420
3421void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003422 const sp<Connection>& connection,
3423 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003424 if (DEBUG_DISPATCH_CYCLE) {
3425 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3426 connection->getInputChannelName().c_str(), toString(notify));
3427 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003428
3429 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003430 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003431 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003432 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003433 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003434
3435 // The connection appears to be unrecoverably broken.
3436 // Ignore already broken or zombie connections.
3437 if (connection->status == Connection::STATUS_NORMAL) {
3438 connection->status = Connection::STATUS_BROKEN;
3439
3440 if (notify) {
3441 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003442 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3443 connection->getInputChannelName().c_str());
3444
3445 auto command = [this, connection]() REQUIRES(mLock) {
3446 if (connection->status == Connection::STATUS_ZOMBIE) return;
3447 scoped_unlock unlock(mLock);
3448 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3449 };
3450 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003451 }
3452 }
3453}
3454
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003455void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3456 while (!queue.empty()) {
3457 DispatchEntry* dispatchEntry = queue.front();
3458 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003459 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003460 }
3461}
3462
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003463void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003464 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003465 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003466 }
3467 delete dispatchEntry;
3468}
3469
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003470int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3471 std::scoped_lock _l(mLock);
3472 sp<Connection> connection = getConnectionLocked(connectionToken);
3473 if (connection == nullptr) {
3474 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3475 connectionToken.get(), events);
3476 return 0; // remove the callback
3477 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003478
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003479 bool notify;
3480 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3481 if (!(events & ALOOPER_EVENT_INPUT)) {
3482 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3483 "events=0x%x",
3484 connection->getInputChannelName().c_str(), events);
3485 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003486 }
3487
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003488 nsecs_t currentTime = now();
3489 bool gotOne = false;
3490 status_t status = OK;
3491 for (;;) {
3492 Result<InputPublisher::ConsumerResponse> result =
3493 connection->inputPublisher.receiveConsumerResponse();
3494 if (!result.ok()) {
3495 status = result.error().code();
3496 break;
3497 }
3498
3499 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3500 const InputPublisher::Finished& finish =
3501 std::get<InputPublisher::Finished>(*result);
3502 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3503 finish.consumeTime);
3504 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003505 if (shouldReportMetricsForConnection(*connection)) {
3506 const InputPublisher::Timeline& timeline =
3507 std::get<InputPublisher::Timeline>(*result);
3508 mLatencyTracker
3509 .trackGraphicsLatency(timeline.inputEventId,
3510 connection->inputChannel->getConnectionToken(),
3511 std::move(timeline.graphicsTimeline));
3512 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003513 }
3514 gotOne = true;
3515 }
3516 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003517 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003518 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003519 return 1;
3520 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003521 }
3522
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003523 notify = status != DEAD_OBJECT || !connection->monitor;
3524 if (notify) {
3525 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3526 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3527 status);
3528 }
3529 } else {
3530 // Monitor channels are never explicitly unregistered.
3531 // We do it automatically when the remote endpoint is closed so don't warn about them.
3532 const bool stillHaveWindowHandle =
3533 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3534 notify = !connection->monitor && stillHaveWindowHandle;
3535 if (notify) {
3536 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3537 connection->getInputChannelName().c_str(), events);
3538 }
3539 }
3540
3541 // Remove the channel.
3542 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3543 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003544}
3545
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003546void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003547 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003548 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003549 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003550 }
3551}
3552
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003553void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003554 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003555 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3556 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3557}
3558
3559void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3560 const CancelationOptions& options,
3561 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3562 for (const auto& it : monitorsByDisplay) {
3563 const std::vector<Monitor>& monitors = it.second;
3564 for (const Monitor& monitor : monitors) {
3565 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003566 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003567 }
3568}
3569
Michael Wrightd02c5b62014-02-10 15:10:22 -08003570void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003571 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003572 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003573 if (connection == nullptr) {
3574 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003575 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003576
3577 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003578}
3579
3580void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3581 const sp<Connection>& connection, const CancelationOptions& options) {
3582 if (connection->status == Connection::STATUS_BROKEN) {
3583 return;
3584 }
3585
3586 nsecs_t currentTime = now();
3587
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003588 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003589 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003590
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003591 if (cancelationEvents.empty()) {
3592 return;
3593 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003594 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3595 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3596 "with reality: %s, mode=%d.",
3597 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3598 options.mode);
3599 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003600
3601 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003602 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003603 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3604 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003605 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003606 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003607 target.globalScaleFactor = windowInfo->globalScaleFactor;
3608 }
3609 target.inputChannel = connection->inputChannel;
3610 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3611
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003612 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003613 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003614 switch (cancelationEventEntry->type) {
3615 case EventEntry::Type::KEY: {
3616 logOutboundKeyDetails("cancel - ",
3617 static_cast<const KeyEntry&>(*cancelationEventEntry));
3618 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003619 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003620 case EventEntry::Type::MOTION: {
3621 logOutboundMotionDetails("cancel - ",
3622 static_cast<const MotionEntry&>(*cancelationEventEntry));
3623 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003624 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003625 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003626 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003627 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3628 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003629 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08003630 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003631 break;
3632 }
3633 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003634 case EventEntry::Type::DEVICE_RESET:
3635 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003636 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003637 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003638 break;
3639 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003640 }
3641
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003642 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3643 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003644 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003645
3646 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003647}
3648
Svet Ganov5d3bc372020-01-26 23:11:07 -08003649void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3650 const sp<Connection>& connection) {
3651 if (connection->status == Connection::STATUS_BROKEN) {
3652 return;
3653 }
3654
3655 nsecs_t currentTime = now();
3656
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003657 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003658 connection->inputState.synthesizePointerDownEvents(currentTime);
3659
3660 if (downEvents.empty()) {
3661 return;
3662 }
3663
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003664 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003665 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3666 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003667 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003668
3669 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003670 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003671 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3672 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003673 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003674 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003675 target.globalScaleFactor = windowInfo->globalScaleFactor;
3676 }
3677 target.inputChannel = connection->inputChannel;
3678 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3679
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003680 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003681 switch (downEventEntry->type) {
3682 case EventEntry::Type::MOTION: {
3683 logOutboundMotionDetails("down - ",
3684 static_cast<const MotionEntry&>(*downEventEntry));
3685 break;
3686 }
3687
3688 case EventEntry::Type::KEY:
3689 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003690 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08003691 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003692 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003693 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003694 case EventEntry::Type::SENSOR:
3695 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003696 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003697 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003698 break;
3699 }
3700 }
3701
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003702 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3703 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003704 }
3705
3706 startDispatchCycleLocked(currentTime, connection);
3707}
3708
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003709std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3710 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003711 ALOG_ASSERT(pointerIds.value != 0);
3712
3713 uint32_t splitPointerIndexMap[MAX_POINTERS];
3714 PointerProperties splitPointerProperties[MAX_POINTERS];
3715 PointerCoords splitPointerCoords[MAX_POINTERS];
3716
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003717 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003718 uint32_t splitPointerCount = 0;
3719
3720 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003721 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003722 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003723 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003724 uint32_t pointerId = uint32_t(pointerProperties.id);
3725 if (pointerIds.hasBit(pointerId)) {
3726 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3727 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3728 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003729 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003730 splitPointerCount += 1;
3731 }
3732 }
3733
3734 if (splitPointerCount != pointerIds.count()) {
3735 // This is bad. We are missing some of the pointers that we expected to deliver.
3736 // Most likely this indicates that we received an ACTION_MOVE events that has
3737 // different pointer ids than we expected based on the previous ACTION_DOWN
3738 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3739 // in this way.
3740 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003741 "we expected there to be %d pointers. This probably means we received "
3742 "a broken sequence of pointer ids from the input device.",
3743 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003744 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003745 }
3746
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003747 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003748 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003749 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3750 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003751 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3752 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003753 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003754 uint32_t pointerId = uint32_t(pointerProperties.id);
3755 if (pointerIds.hasBit(pointerId)) {
3756 if (pointerIds.count() == 1) {
3757 // The first/last pointer went down/up.
3758 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003759 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003760 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3761 ? AMOTION_EVENT_ACTION_CANCEL
3762 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003763 } else {
3764 // A secondary pointer went down/up.
3765 uint32_t splitPointerIndex = 0;
3766 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3767 splitPointerIndex += 1;
3768 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003769 action = maskedAction |
3770 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003771 }
3772 } else {
3773 // An unrelated pointer changed.
3774 action = AMOTION_EVENT_ACTION_MOVE;
3775 }
3776 }
3777
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003778 int32_t newId = mIdGenerator.nextId();
3779 if (ATRACE_ENABLED()) {
3780 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3781 ") to MotionEvent(id=0x%" PRIx32 ").",
3782 originalMotionEntry.id, newId);
3783 ATRACE_NAME(message.c_str());
3784 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003785 std::unique_ptr<MotionEntry> splitMotionEntry =
3786 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3787 originalMotionEntry.deviceId, originalMotionEntry.source,
3788 originalMotionEntry.displayId,
3789 originalMotionEntry.policyFlags, action,
3790 originalMotionEntry.actionButton,
3791 originalMotionEntry.flags, originalMotionEntry.metaState,
3792 originalMotionEntry.buttonState,
3793 originalMotionEntry.classification,
3794 originalMotionEntry.edgeFlags,
3795 originalMotionEntry.xPrecision,
3796 originalMotionEntry.yPrecision,
3797 originalMotionEntry.xCursorPosition,
3798 originalMotionEntry.yCursorPosition,
3799 originalMotionEntry.downTime, splitPointerCount,
3800 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003801
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003802 if (originalMotionEntry.injectionState) {
3803 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003804 splitMotionEntry->injectionState->refCount += 1;
3805 }
3806
3807 return splitMotionEntry;
3808}
3809
3810void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003811 if (DEBUG_INBOUND_EVENT_DETAILS) {
3812 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3813 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003814
3815 bool needWake;
3816 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003817 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003818
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003819 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3820 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3821 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003822 } // release lock
3823
3824 if (needWake) {
3825 mLooper->wake();
3826 }
3827}
3828
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003829/**
3830 * If one of the meta shortcuts is detected, process them here:
3831 * Meta + Backspace -> generate BACK
3832 * Meta + Enter -> generate HOME
3833 * This will potentially overwrite keyCode and metaState.
3834 */
3835void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003836 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003837 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3838 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3839 if (keyCode == AKEYCODE_DEL) {
3840 newKeyCode = AKEYCODE_BACK;
3841 } else if (keyCode == AKEYCODE_ENTER) {
3842 newKeyCode = AKEYCODE_HOME;
3843 }
3844 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003845 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003846 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003847 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003848 keyCode = newKeyCode;
3849 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3850 }
3851 } else if (action == AKEY_EVENT_ACTION_UP) {
3852 // In order to maintain a consistent stream of up and down events, check to see if the key
3853 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3854 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003855 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003856 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003857 auto replacementIt = mReplacedKeys.find(replacement);
3858 if (replacementIt != mReplacedKeys.end()) {
3859 keyCode = replacementIt->second;
3860 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003861 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3862 }
3863 }
3864}
3865
Michael Wrightd02c5b62014-02-10 15:10:22 -08003866void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003867 if (DEBUG_INBOUND_EVENT_DETAILS) {
3868 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3869 "policyFlags=0x%x, action=0x%x, "
3870 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3871 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3872 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3873 args->downTime);
3874 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003875 if (!validateKeyEvent(args->action)) {
3876 return;
3877 }
3878
3879 uint32_t policyFlags = args->policyFlags;
3880 int32_t flags = args->flags;
3881 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003882 // InputDispatcher tracks and generates key repeats on behalf of
3883 // whatever notifies it, so repeatCount should always be set to 0
3884 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003885 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3886 policyFlags |= POLICY_FLAG_VIRTUAL;
3887 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3888 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003889 if (policyFlags & POLICY_FLAG_FUNCTION) {
3890 metaState |= AMETA_FUNCTION_ON;
3891 }
3892
3893 policyFlags |= POLICY_FLAG_TRUSTED;
3894
Michael Wright78f24442014-08-06 15:55:28 -07003895 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003896 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003897
Michael Wrightd02c5b62014-02-10 15:10:22 -08003898 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003899 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003900 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3901 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003902
Michael Wright2b3c3302018-03-02 17:19:13 +00003903 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003904 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003905 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3906 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003907 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003908 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003909
Michael Wrightd02c5b62014-02-10 15:10:22 -08003910 bool needWake;
3911 { // acquire lock
3912 mLock.lock();
3913
3914 if (shouldSendKeyToInputFilterLocked(args)) {
3915 mLock.unlock();
3916
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003917 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003918 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3919 return; // event was consumed by the filter
3920 }
3921
3922 mLock.lock();
3923 }
3924
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003925 std::unique_ptr<KeyEntry> newEntry =
3926 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3927 args->displayId, policyFlags, args->action, flags,
3928 keyCode, args->scanCode, metaState, repeatCount,
3929 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003930
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003931 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003932 mLock.unlock();
3933 } // release lock
3934
3935 if (needWake) {
3936 mLooper->wake();
3937 }
3938}
3939
3940bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3941 return mInputFilterEnabled;
3942}
3943
3944void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003945 if (DEBUG_INBOUND_EVENT_DETAILS) {
3946 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3947 "displayId=%" PRId32 ", policyFlags=0x%x, "
3948 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3949 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
3950 "yCursorPosition=%f, downTime=%" PRId64,
3951 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3952 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3953 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3954 args->xCursorPosition, args->yCursorPosition, args->downTime);
3955 for (uint32_t i = 0; i < args->pointerCount; i++) {
3956 ALOGD(" Pointer %d: id=%d, toolType=%d, "
3957 "x=%f, y=%f, pressure=%f, size=%f, "
3958 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3959 "orientation=%f",
3960 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3961 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3962 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3963 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3964 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3965 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3966 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3967 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3968 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3969 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
3970 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003971 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003972 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3973 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003974 return;
3975 }
3976
3977 uint32_t policyFlags = args->policyFlags;
3978 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003979
3980 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003981 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003982 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3983 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003984 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003985 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003986
3987 bool needWake;
3988 { // acquire lock
3989 mLock.lock();
3990
3991 if (shouldSendMotionToInputFilterLocked(args)) {
3992 mLock.unlock();
3993
3994 MotionEvent event;
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003995 ui::Transform identityTransform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003996 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3997 args->action, args->actionButton, args->flags, args->edgeFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003998 args->metaState, args->buttonState, args->classification,
3999 identityTransform, args->xPrecision, args->yPrecision,
4000 args->xCursorPosition, args->yCursorPosition, identityTransform,
4001 args->downTime, args->eventTime, args->pointerCount,
4002 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004003
4004 policyFlags |= POLICY_FLAG_FILTERED;
4005 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
4006 return; // event was consumed by the filter
4007 }
4008
4009 mLock.lock();
4010 }
4011
4012 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004013 std::unique_ptr<MotionEntry> newEntry =
4014 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
4015 args->source, args->displayId, policyFlags,
4016 args->action, args->actionButton, args->flags,
4017 args->metaState, args->buttonState,
4018 args->classification, args->edgeFlags,
4019 args->xPrecision, args->yPrecision,
4020 args->xCursorPosition, args->yCursorPosition,
4021 args->downTime, args->pointerCount,
4022 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004023
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004024 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4025 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
4026 !mInputFilterEnabled) {
4027 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
4028 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
4029 }
4030
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004031 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004032 mLock.unlock();
4033 } // release lock
4034
4035 if (needWake) {
4036 mLooper->wake();
4037 }
4038}
4039
Chris Yef59a2f42020-10-16 12:55:26 -07004040void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004041 if (DEBUG_INBOUND_EVENT_DETAILS) {
4042 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4043 " sensorType=%s",
4044 args->id, args->eventTime, args->deviceId, args->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08004045 ftl::enum_string(args->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004046 }
Chris Yef59a2f42020-10-16 12:55:26 -07004047
4048 bool needWake;
4049 { // acquire lock
4050 mLock.lock();
4051
4052 // Just enqueue a new sensor event.
4053 std::unique_ptr<SensorEntry> newEntry =
4054 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
4055 args->source, 0 /* policyFlags*/, args->hwTimestamp,
4056 args->sensorType, args->accuracy,
4057 args->accuracyChanged, args->values);
4058
4059 needWake = enqueueInboundEventLocked(std::move(newEntry));
4060 mLock.unlock();
4061 } // release lock
4062
4063 if (needWake) {
4064 mLooper->wake();
4065 }
4066}
4067
Chris Yefb552902021-02-03 17:18:37 -08004068void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004069 if (DEBUG_INBOUND_EVENT_DETAILS) {
4070 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
4071 args->deviceId, args->isOn);
4072 }
Chris Yefb552902021-02-03 17:18:37 -08004073 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
4074}
4075
Michael Wrightd02c5b62014-02-10 15:10:22 -08004076bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08004077 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004078}
4079
4080void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004081 if (DEBUG_INBOUND_EVENT_DETAILS) {
4082 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4083 "switchMask=0x%08x",
4084 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
4085 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004086
4087 uint32_t policyFlags = args->policyFlags;
4088 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004089 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004090}
4091
4092void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004093 if (DEBUG_INBOUND_EVENT_DETAILS) {
4094 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
4095 args->deviceId);
4096 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004097
4098 bool needWake;
4099 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004100 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004101
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004102 std::unique_ptr<DeviceResetEntry> newEntry =
4103 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
4104 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004105 } // release lock
4106
4107 if (needWake) {
4108 mLooper->wake();
4109 }
4110}
4111
Prabir Pradhan7e186182020-11-10 13:56:45 -08004112void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004113 if (DEBUG_INBOUND_EVENT_DETAILS) {
4114 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004115 args->request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004116 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004117
Prabir Pradhan99987712020-11-10 18:43:05 -08004118 bool needWake;
4119 { // acquire lock
4120 std::scoped_lock _l(mLock);
4121 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004122 args->request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004123 needWake = enqueueInboundEventLocked(std::move(entry));
4124 } // release lock
4125
4126 if (needWake) {
4127 mLooper->wake();
4128 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004129}
4130
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004131InputEventInjectionResult InputDispatcher::injectInputEvent(
4132 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4133 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004134 if (DEBUG_INBOUND_EVENT_DETAILS) {
4135 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
4136 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4137 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
4138 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004139 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004140
4141 policyFlags |= POLICY_FLAG_INJECTED;
4142 if (hasInjectionPermission(injectorPid, injectorUid)) {
4143 policyFlags |= POLICY_FLAG_TRUSTED;
4144 }
4145
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004146 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004147 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4148 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4149 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4150 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4151 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004152 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004153 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004154 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004155 }
4156
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004157 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004158 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004159 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004160 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4161 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004162 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004163 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004164 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004165
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004166 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004167 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4168 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4169 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004170 int32_t keyCode = incomingKey.getKeyCode();
4171 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004172 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004173 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004174 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004175 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004176 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4177 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4178 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004179
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004180 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4181 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004182 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004183
4184 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4185 android::base::Timer t;
4186 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4187 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4188 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4189 std::to_string(t.duration().count()).c_str());
4190 }
4191 }
4192
4193 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004194 std::unique_ptr<KeyEntry> injectedEntry =
4195 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004196 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004197 incomingKey.getDisplayId(), policyFlags, action,
4198 flags, keyCode, incomingKey.getScanCode(), metaState,
4199 incomingKey.getRepeatCount(),
4200 incomingKey.getDownTime());
4201 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004202 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004203 }
4204
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004205 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004206 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
4207 int32_t action = motionEvent.getAction();
4208 size_t pointerCount = motionEvent.getPointerCount();
4209 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
4210 int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004211 int32_t flags = motionEvent.getFlags();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004212 int32_t displayId = motionEvent.getDisplayId();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004213 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004214 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004215 }
4216
4217 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004218 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004219 android::base::Timer t;
4220 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4221 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4222 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4223 std::to_string(t.duration().count()).c_str());
4224 }
4225 }
4226
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004227 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4228 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4229 }
4230
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004231 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004232 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4233 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004234 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004235 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4236 resolvedDeviceId, motionEvent.getSource(),
4237 motionEvent.getDisplayId(), policyFlags, action,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004238 actionButton, flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004239 motionEvent.getButtonState(),
4240 motionEvent.getClassification(),
4241 motionEvent.getEdgeFlags(),
4242 motionEvent.getXPrecision(),
4243 motionEvent.getYPrecision(),
4244 motionEvent.getRawXCursorPosition(),
4245 motionEvent.getRawYCursorPosition(),
4246 motionEvent.getDownTime(), uint32_t(pointerCount),
4247 pointerProperties, samplePointerCoords,
4248 motionEvent.getXOffset(),
4249 motionEvent.getYOffset());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004250 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004251 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004252 sampleEventTimes += 1;
4253 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004254 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004255 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4256 resolvedDeviceId, motionEvent.getSource(),
4257 motionEvent.getDisplayId(), policyFlags,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004258 action, actionButton, flags,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004259 motionEvent.getMetaState(),
4260 motionEvent.getButtonState(),
4261 motionEvent.getClassification(),
4262 motionEvent.getEdgeFlags(),
4263 motionEvent.getXPrecision(),
4264 motionEvent.getYPrecision(),
4265 motionEvent.getRawXCursorPosition(),
4266 motionEvent.getRawYCursorPosition(),
4267 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004268 uint32_t(pointerCount), pointerProperties,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004269 samplePointerCoords, motionEvent.getXOffset(),
4270 motionEvent.getYOffset());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004271 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004272 }
4273 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004274 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004275
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004276 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004277 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004278 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004279 }
4280
4281 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004282 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004283 injectionState->injectionIsAsync = true;
4284 }
4285
4286 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004287 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004288
4289 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004290 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004291 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004292 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004293 }
4294
4295 mLock.unlock();
4296
4297 if (needWake) {
4298 mLooper->wake();
4299 }
4300
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004301 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004302 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004303 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004304
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004305 if (syncMode == InputEventInjectionSync::NONE) {
4306 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004307 } else {
4308 for (;;) {
4309 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004310 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004311 break;
4312 }
4313
4314 nsecs_t remainingTimeout = endTime - now();
4315 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004316 if (DEBUG_INJECTION) {
4317 ALOGD("injectInputEvent - Timed out waiting for injection result "
4318 "to become available.");
4319 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004320 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004321 break;
4322 }
4323
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004324 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004325 }
4326
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004327 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4328 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004329 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004330 if (DEBUG_INJECTION) {
4331 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4332 injectionState->pendingForegroundDispatches);
4333 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004334 nsecs_t remainingTimeout = endTime - now();
4335 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004336 if (DEBUG_INJECTION) {
4337 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4338 "dispatches to finish.");
4339 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004340 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004341 break;
4342 }
4343
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004344 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004345 }
4346 }
4347 }
4348
4349 injectionState->release();
4350 } // release lock
4351
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004352 if (DEBUG_INJECTION) {
4353 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
4354 injectionResult, injectorPid, injectorUid);
4355 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004356
4357 return injectionResult;
4358}
4359
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004360std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004361 std::array<uint8_t, 32> calculatedHmac;
4362 std::unique_ptr<VerifiedInputEvent> result;
4363 switch (event.getType()) {
4364 case AINPUT_EVENT_TYPE_KEY: {
4365 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4366 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4367 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004368 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004369 break;
4370 }
4371 case AINPUT_EVENT_TYPE_MOTION: {
4372 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4373 VerifiedMotionEvent verifiedMotionEvent =
4374 verifiedMotionEventFromMotionEvent(motionEvent);
4375 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004376 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004377 break;
4378 }
4379 default: {
4380 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4381 return nullptr;
4382 }
4383 }
4384 if (calculatedHmac == INVALID_HMAC) {
4385 return nullptr;
4386 }
4387 if (calculatedHmac != event.getHmac()) {
4388 return nullptr;
4389 }
4390 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004391}
4392
Michael Wrightd02c5b62014-02-10 15:10:22 -08004393bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004394 return injectorUid == 0 ||
4395 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004396}
4397
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004398void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004399 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004400 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004401 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004402 if (DEBUG_INJECTION) {
4403 ALOGD("Setting input event injection result to %d. "
4404 "injectorPid=%d, injectorUid=%d",
4405 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
4406 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004407
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004408 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004409 // Log the outcome since the injector did not wait for the injection result.
4410 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004411 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004412 ALOGV("Asynchronous input event injection succeeded.");
4413 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004414 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004415 ALOGW("Asynchronous input event injection failed.");
4416 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004417 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004418 ALOGW("Asynchronous input event injection permission denied.");
4419 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004420 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004421 ALOGW("Asynchronous input event injection timed out.");
4422 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004423 case InputEventInjectionResult::PENDING:
4424 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4425 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004426 }
4427 }
4428
4429 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004430 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004431 }
4432}
4433
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004434void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4435 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004436 if (injectionState) {
4437 injectionState->pendingForegroundDispatches += 1;
4438 }
4439}
4440
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004441void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4442 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004443 if (injectionState) {
4444 injectionState->pendingForegroundDispatches -= 1;
4445
4446 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004447 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004448 }
4449 }
4450}
4451
chaviw98318de2021-05-19 16:45:23 -05004452const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004453 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004454 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004455 auto it = mWindowHandlesByDisplay.find(displayId);
4456 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004457}
4458
chaviw98318de2021-05-19 16:45:23 -05004459sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004460 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004461 if (windowHandleToken == nullptr) {
4462 return nullptr;
4463 }
4464
Arthur Hungb92218b2018-08-14 12:00:21 +08004465 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004466 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4467 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004468 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004469 return windowHandle;
4470 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004471 }
4472 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004473 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004474}
4475
chaviw98318de2021-05-19 16:45:23 -05004476sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4477 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004478 if (windowHandleToken == nullptr) {
4479 return nullptr;
4480 }
4481
chaviw98318de2021-05-19 16:45:23 -05004482 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004483 if (windowHandle->getToken() == windowHandleToken) {
4484 return windowHandle;
4485 }
4486 }
4487 return nullptr;
4488}
4489
chaviw98318de2021-05-19 16:45:23 -05004490sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4491 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004492 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004493 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4494 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004495 if (handle->getId() == windowHandle->getId() &&
4496 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004497 if (windowHandle->getInfo()->displayId != it.first) {
4498 ALOGE("Found window %s in display %" PRId32
4499 ", but it should belong to display %" PRId32,
4500 windowHandle->getName().c_str(), it.first,
4501 windowHandle->getInfo()->displayId);
4502 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004503 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004504 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004505 }
4506 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004507 return nullptr;
4508}
4509
chaviw98318de2021-05-19 16:45:23 -05004510sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004511 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4512 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004513}
4514
chaviw98318de2021-05-19 16:45:23 -05004515bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004516 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4517 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004518 windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004519 if (connection != nullptr && noInputChannel) {
4520 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4521 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4522 return false;
4523 }
4524
4525 if (connection == nullptr) {
4526 if (!noInputChannel) {
4527 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4528 }
4529 return false;
4530 }
4531 if (!connection->responsive) {
4532 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4533 return false;
4534 }
4535 return true;
4536}
4537
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004538std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4539 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004540 auto connectionIt = mConnectionsByToken.find(token);
4541 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004542 return nullptr;
4543 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004544 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004545}
4546
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004547void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004548 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4549 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004550 // Remove all handles on a display if there are no windows left.
4551 mWindowHandlesByDisplay.erase(displayId);
4552 return;
4553 }
4554
4555 // Since we compare the pointer of input window handles across window updates, we need
4556 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004557 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4558 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4559 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004560 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004561 }
4562
chaviw98318de2021-05-19 16:45:23 -05004563 std::vector<sp<WindowInfoHandle>> newHandles;
4564 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05004565 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004566 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004567 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004568 info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
4569 const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
4570 !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004571 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004572 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004573 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004574 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004575 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004576 }
4577
4578 if (info->displayId != displayId) {
4579 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4580 handle->getName().c_str(), displayId, info->displayId);
4581 continue;
4582 }
4583
Robert Carredd13602020-04-13 17:24:34 -07004584 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4585 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004586 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004587 oldHandle->updateFrom(handle);
4588 newHandles.push_back(oldHandle);
4589 } else {
4590 newHandles.push_back(handle);
4591 }
4592 }
4593
4594 // Insert or replace
4595 mWindowHandlesByDisplay[displayId] = newHandles;
4596}
4597
Arthur Hung72d8dc32020-03-28 00:48:39 +00004598void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004599 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07004600 // TODO(b/198444055): Remove setInputWindows from InputDispatcher.
Arthur Hung72d8dc32020-03-28 00:48:39 +00004601 { // acquire lock
4602 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004603 for (const auto& [displayId, handles] : handlesPerDisplay) {
4604 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004605 }
4606 }
4607 // Wake up poll loop since it may need to make new input dispatching choices.
4608 mLooper->wake();
4609}
4610
Arthur Hungb92218b2018-08-14 12:00:21 +08004611/**
4612 * Called from InputManagerService, update window handle list by displayId that can receive input.
4613 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4614 * If set an empty list, remove all handles from the specific display.
4615 * For focused handle, check if need to change and send a cancel event to previous one.
4616 * For removed handle, check if need to send a cancel event if already in touch.
4617 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004618void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004619 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004620 if (DEBUG_FOCUS) {
4621 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004622 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004623 windowList += iwh->getName() + " ";
4624 }
4625 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4626 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004627
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004628 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
chaviw98318de2021-05-19 16:45:23 -05004629 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004630 const bool noInputWindow =
chaviw98318de2021-05-19 16:45:23 -05004631 window->getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004632 if (noInputWindow && window->getToken() != nullptr) {
4633 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4634 window->getName().c_str());
4635 window->releaseChannel();
4636 }
4637 }
4638
Arthur Hung72d8dc32020-03-28 00:48:39 +00004639 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004640 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004641
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004642 // Save the old windows' orientation by ID before it gets updated.
4643 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004644 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004645 oldWindowOrientations.emplace(handle->getId(),
4646 handle->getInfo()->transform.getOrientation());
4647 }
4648
chaviw98318de2021-05-19 16:45:23 -05004649 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004650
chaviw98318de2021-05-19 16:45:23 -05004651 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004652 if (mLastHoverWindowHandle &&
4653 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4654 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004655 mLastHoverWindowHandle = nullptr;
4656 }
4657
Vishnu Nairc519ff72021-01-21 08:23:08 -08004658 std::optional<FocusResolver::FocusChanges> changes =
4659 mFocusResolver.setInputWindows(displayId, windowHandles);
4660 if (changes) {
4661 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004662 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004663
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004664 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4665 mTouchStatesByDisplay.find(displayId);
4666 if (stateIt != mTouchStatesByDisplay.end()) {
4667 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004668 for (size_t i = 0; i < state.windows.size();) {
4669 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004670 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004671 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004672 ALOGD("Touched window was removed: %s in display %" PRId32,
4673 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004674 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004675 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004676 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4677 if (touchedInputChannel != nullptr) {
4678 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4679 "touched window was removed");
4680 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004681 // Since we are about to drop the touch, cancel the events for the wallpaper as
4682 // well.
4683 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND &&
4684 touchedWindow.windowHandle->getInfo()->hasWallpaper) {
4685 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
4686 if (wallpaper != nullptr) {
4687 sp<Connection> wallpaperConnection =
4688 getConnectionLocked(wallpaper->getToken());
4689 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection,
4690 options);
4691 }
4692 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004693 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004694 state.windows.erase(state.windows.begin() + i);
4695 } else {
4696 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004697 }
4698 }
arthurhungb89ccb02020-12-30 16:19:01 +08004699
arthurhung6d4bed92021-03-17 11:59:33 +08004700 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004701 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004702 if (mDragState &&
4703 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004704 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004705 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004706 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004707 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004708
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004709 if (isPerWindowInputRotationEnabled()) {
4710 // Determine if the orientation of any of the input windows have changed, and cancel all
4711 // pointer events if necessary.
chaviw98318de2021-05-19 16:45:23 -05004712 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4713 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004714 if (newWindowHandle != nullptr &&
4715 newWindowHandle->getInfo()->transform.getOrientation() !=
4716 oldWindowOrientations[oldWindowHandle->getId()]) {
4717 std::shared_ptr<InputChannel> inputChannel =
4718 getInputChannelLocked(newWindowHandle->getToken());
4719 if (inputChannel != nullptr) {
4720 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4721 "touched window's orientation changed");
4722 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4723 }
4724 }
4725 }
4726 }
4727
Arthur Hung72d8dc32020-03-28 00:48:39 +00004728 // Release information for windows that are no longer present.
4729 // This ensures that unused input channels are released promptly.
4730 // Otherwise, they might stick around until the window handle is destroyed
4731 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004732 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004733 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004734 if (DEBUG_FOCUS) {
4735 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004736 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004737 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004738 // To avoid making too many calls into the compat framework, only
4739 // check for window flags when windows are going away.
4740 // TODO(b/157929241) : delete this. This is only needed temporarily
4741 // in order to gather some data about the flag usage
chaviw98318de2021-05-19 16:45:23 -05004742 if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004743 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4744 oldWindowHandle->getName().c_str());
4745 if (mCompatService != nullptr) {
4746 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4747 oldWindowHandle->getInfo()->ownerUid);
4748 }
4749 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004750 }
chaviw291d88a2019-02-14 10:33:58 -08004751 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004752}
4753
4754void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004755 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004756 if (DEBUG_FOCUS) {
4757 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4758 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4759 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004760 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004761 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004762 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004763 } // release lock
4764
4765 // Wake up poll loop since it may need to make new input dispatching choices.
4766 mLooper->wake();
4767}
4768
Vishnu Nair599f1412021-06-21 10:39:58 -07004769void InputDispatcher::setFocusedApplicationLocked(
4770 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4771 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4772 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4773
4774 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4775 return; // This application is already focused. No need to wake up or change anything.
4776 }
4777
4778 // Set the new application handle.
4779 if (inputApplicationHandle != nullptr) {
4780 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4781 } else {
4782 mFocusedApplicationHandlesByDisplay.erase(displayId);
4783 }
4784
4785 // No matter what the old focused application was, stop waiting on it because it is
4786 // no longer focused.
4787 resetNoFocusedWindowTimeoutLocked();
4788}
4789
Tiger Huang721e26f2018-07-24 22:26:19 +08004790/**
4791 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4792 * the display not specified.
4793 *
4794 * We track any unreleased events for each window. If a window loses the ability to receive the
4795 * released event, we will send a cancel event to it. So when the focused display is changed, we
4796 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4797 * display. The display-specified events won't be affected.
4798 */
4799void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004800 if (DEBUG_FOCUS) {
4801 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4802 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004803 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004804 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004805
4806 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004807 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004808 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004809 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004810 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004811 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004812 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004813 CancelationOptions
4814 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4815 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004816 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004817 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4818 }
4819 }
4820 mFocusedDisplayId = displayId;
4821
Chris Ye3c2d6f52020-08-09 10:39:48 -07004822 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004823 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004824 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004825
Vishnu Nairad321cd2020-08-20 16:40:21 -07004826 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004827 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004828 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004829 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004830 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004831 }
4832 }
4833 }
4834
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004835 if (DEBUG_FOCUS) {
4836 logDispatchStateLocked();
4837 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004838 } // release lock
4839
4840 // Wake up poll loop since it may need to make new input dispatching choices.
4841 mLooper->wake();
4842}
4843
Michael Wrightd02c5b62014-02-10 15:10:22 -08004844void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004845 if (DEBUG_FOCUS) {
4846 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4847 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004848
4849 bool changed;
4850 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004851 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004852
4853 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4854 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004855 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004856 }
4857
4858 if (mDispatchEnabled && !enabled) {
4859 resetAndDropEverythingLocked("dispatcher is being disabled");
4860 }
4861
4862 mDispatchEnabled = enabled;
4863 mDispatchFrozen = frozen;
4864 changed = true;
4865 } else {
4866 changed = false;
4867 }
4868
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004869 if (DEBUG_FOCUS) {
4870 logDispatchStateLocked();
4871 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004872 } // release lock
4873
4874 if (changed) {
4875 // Wake up poll loop since it may need to make new input dispatching choices.
4876 mLooper->wake();
4877 }
4878}
4879
4880void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004881 if (DEBUG_FOCUS) {
4882 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4883 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004884
4885 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004886 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004887
4888 if (mInputFilterEnabled == enabled) {
4889 return;
4890 }
4891
4892 mInputFilterEnabled = enabled;
4893 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4894 } // release lock
4895
4896 // Wake up poll loop since there might be work to do to drop everything.
4897 mLooper->wake();
4898}
4899
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004900void InputDispatcher::setInTouchMode(bool inTouchMode) {
4901 std::scoped_lock lock(mLock);
4902 mInTouchMode = inTouchMode;
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004903 // TODO(b/193718270): Fire TouchModeEvent here.
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004904}
4905
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004906void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4907 if (opacity < 0 || opacity > 1) {
4908 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4909 return;
4910 }
4911
4912 std::scoped_lock lock(mLock);
4913 mMaximumObscuringOpacityForTouch = opacity;
4914}
4915
4916void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4917 std::scoped_lock lock(mLock);
4918 mBlockUntrustedTouchesMode = mode;
4919}
4920
Arthur Hungabbb9d82021-09-01 14:52:30 +00004921std::pair<TouchState*, TouchedWindow*> InputDispatcher::findTouchStateAndWindowLocked(
4922 const sp<IBinder>& token) {
4923 for (auto& [displayId, state] : mTouchStatesByDisplay) {
4924 for (TouchedWindow& w : state.windows) {
4925 if (w.windowHandle->getToken() == token) {
4926 return std::make_pair(&state, &w);
4927 }
4928 }
4929 }
4930 return std::make_pair(nullptr, nullptr);
4931}
4932
arthurhungb89ccb02020-12-30 16:19:01 +08004933bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4934 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004935 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004936 if (DEBUG_FOCUS) {
4937 ALOGD("Trivial transfer to same window.");
4938 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004939 return true;
4940 }
4941
Michael Wrightd02c5b62014-02-10 15:10:22 -08004942 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004943 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004944
Arthur Hungabbb9d82021-09-01 14:52:30 +00004945 // Find the target touch state and touched window by fromToken.
4946 auto [state, touchedWindow] = findTouchStateAndWindowLocked(fromToken);
4947 if (state == nullptr || touchedWindow == nullptr) {
4948 ALOGD("Focus transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004949 return false;
4950 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00004951
4952 const int32_t displayId = state->displayId;
4953 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
4954 if (toWindowHandle == nullptr) {
4955 ALOGW("Cannot transfer focus because to window not found.");
4956 return false;
4957 }
4958
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004959 if (DEBUG_FOCUS) {
4960 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00004961 touchedWindow->windowHandle->getName().c_str(),
4962 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004963 }
4964
Arthur Hungabbb9d82021-09-01 14:52:30 +00004965 // Erase old window.
4966 int32_t oldTargetFlags = touchedWindow->targetFlags;
4967 BitSet32 pointerIds = touchedWindow->pointerIds;
4968 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004969
Arthur Hungabbb9d82021-09-01 14:52:30 +00004970 // Add new window.
4971 int32_t newTargetFlags = oldTargetFlags &
4972 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4973 InputTarget::FLAG_DISPATCH_AS_IS);
4974 state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004975
Arthur Hungabbb9d82021-09-01 14:52:30 +00004976 // Store the dragging window.
4977 if (isDragDrop) {
4978 mDragState = std::make_unique<DragState>(toWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004979 }
4980
Arthur Hungabbb9d82021-09-01 14:52:30 +00004981 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004982 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4983 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004984 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004985 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004986 CancelationOptions
4987 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4988 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004989 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004990 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004991 }
4992
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004993 if (DEBUG_FOCUS) {
4994 logDispatchStateLocked();
4995 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004996 } // release lock
4997
4998 // Wake up poll loop since it may need to make new input dispatching choices.
4999 mLooper->wake();
5000 return true;
5001}
5002
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005003// Binder call
5004bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
5005 sp<IBinder> fromToken;
5006 { // acquire lock
5007 std::scoped_lock _l(mLock);
5008
Arthur Hungabbb9d82021-09-01 14:52:30 +00005009 auto it = std::find_if(mTouchStatesByDisplay.begin(), mTouchStatesByDisplay.end(),
5010 [](const auto& pair) { return pair.second.windows.size() == 1; });
5011 if (it == mTouchStatesByDisplay.end()) {
5012 ALOGW("Cannot transfer touch state because there is no exact window being touched");
5013 return false;
5014 }
5015 const int32_t displayId = it->first;
5016 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005017 if (toWindowHandle == nullptr) {
5018 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
5019 return false;
5020 }
5021
Arthur Hungabbb9d82021-09-01 14:52:30 +00005022 TouchState& state = it->second;
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005023 const TouchedWindow& touchedWindow = state.windows[0];
5024 fromToken = touchedWindow.windowHandle->getToken();
5025 } // release lock
5026
5027 return transferTouchFocus(fromToken, destChannelToken);
5028}
5029
Michael Wrightd02c5b62014-02-10 15:10:22 -08005030void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005031 if (DEBUG_FOCUS) {
5032 ALOGD("Resetting and dropping all events (%s).", reason);
5033 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005034
5035 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
5036 synthesizeCancelationEventsForAllConnectionsLocked(options);
5037
5038 resetKeyRepeatLocked();
5039 releasePendingEventLocked();
5040 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005041 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005042
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005043 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005044 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005045 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07005046 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005047}
5048
5049void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005050 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005051 dumpDispatchStateLocked(dump);
5052
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005053 std::istringstream stream(dump);
5054 std::string line;
5055
5056 while (std::getline(stream, line, '\n')) {
5057 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005058 }
5059}
5060
Prabir Pradhan99987712020-11-10 18:43:05 -08005061std::string InputDispatcher::dumpPointerCaptureStateLocked() {
5062 std::string dump;
5063
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005064 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5065 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005066
5067 std::string windowName = "None";
5068 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005069 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005070 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5071 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5072 : "token has capture without window";
5073 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005074 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005075
5076 return dump;
5077}
5078
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005079void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005080 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5081 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5082 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005083 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005084
Tiger Huang721e26f2018-07-24 22:26:19 +08005085 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5086 dump += StringPrintf(INDENT "FocusedApplications:\n");
5087 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5088 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005089 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005090 const std::chrono::duration timeout =
5091 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005092 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005093 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005094 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005095 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005096 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005097 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005098 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005099
Vishnu Nairc519ff72021-01-21 08:23:08 -08005100 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005101 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005102
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005103 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005104 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005105 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
5106 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005107 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005108 state.displayId, toString(state.down), toString(state.split),
5109 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005110 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005111 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005112 for (size_t i = 0; i < state.windows.size(); i++) {
5113 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005114 dump += StringPrintf(INDENT4
5115 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
5116 i, touchedWindow.windowHandle->getName().c_str(),
5117 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005118 }
5119 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005120 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005121 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005122 }
5123 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005124 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005125 }
5126
arthurhung6d4bed92021-03-17 11:59:33 +08005127 if (mDragState) {
5128 dump += StringPrintf(INDENT "DragState:\n");
5129 mDragState->dump(dump, INDENT2);
5130 }
5131
Arthur Hungb92218b2018-08-14 12:00:21 +08005132 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005133 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5134 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5135 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5136 const auto& displayInfo = it->second;
5137 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5138 displayInfo.logicalHeight);
5139 displayInfo.transform.dump(dump, "transform", INDENT4);
5140 } else {
5141 dump += INDENT2 "No DisplayInfo found!\n";
5142 }
5143
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005144 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005145 dump += INDENT2 "Windows:\n";
5146 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005147 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5148 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005149
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005150 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005151 "paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005152 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005153 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005154 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005155 "applicationInfo.name=%s, "
5156 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005157 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005158 i, windowInfo->name.c_str(), windowInfo->id,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005159 windowInfo->displayId, toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07005160 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005161 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005162 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01005163 windowInfo->flags.string().c_str(),
Dominik Laskowski75788452021-02-09 18:51:25 -08005164 ftl::enum_string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01005165 windowInfo->frameLeft, windowInfo->frameTop,
5166 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005167 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005168 windowInfo->applicationInfo.name.c_str(),
5169 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005170 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01005171 dump += StringPrintf(", inputFeatures=%s",
5172 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005173 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005174 "ms, trustedOverlay=%s, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005175 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005176 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005177 millis(windowInfo->dispatchingTimeout),
5178 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005179 toString(windowInfo->token != nullptr),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005180 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005181 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005182 }
5183 } else {
5184 dump += INDENT2 "Windows: <none>\n";
5185 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005186 }
5187 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005188 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005189 }
5190
Michael Wright3dd60e22019-03-27 22:06:44 +00005191 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005192 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005193 const std::vector<Monitor>& monitors = it.second;
5194 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
5195 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005196 }
5197 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005198 const std::vector<Monitor>& monitors = it.second;
5199 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
5200 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005201 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005202 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00005203 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005204 }
5205
5206 nsecs_t currentTime = now();
5207
5208 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005209 if (!mRecentQueue.empty()) {
5210 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005211 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005212 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005213 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005214 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005215 }
5216 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005217 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005218 }
5219
5220 // Dump event currently being dispatched.
5221 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005222 dump += INDENT "PendingEvent:\n";
5223 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005224 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005225 dump += StringPrintf(", age=%" PRId64 "ms\n",
5226 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005227 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005228 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005229 }
5230
5231 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005232 if (!mInboundQueue.empty()) {
5233 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005234 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005235 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005236 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005237 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005238 }
5239 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005240 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005241 }
5242
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005243 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005244 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005245 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5246 const KeyReplacement& replacement = pair.first;
5247 int32_t newKeyCode = pair.second;
5248 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005249 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005250 }
5251 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005252 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005253 }
5254
Prabir Pradhancef936d2021-07-21 16:17:52 +00005255 if (!mCommandQueue.empty()) {
5256 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5257 } else {
5258 dump += INDENT "CommandQueue: <empty>\n";
5259 }
5260
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005261 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005262 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005263 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005264 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005265 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005266 connection->inputChannel->getFd().get(),
5267 connection->getInputChannelName().c_str(),
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005268 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005269 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005270
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005271 if (!connection->outboundQueue.empty()) {
5272 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5273 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005274 dump += dumpQueue(connection->outboundQueue, currentTime);
5275
Michael Wrightd02c5b62014-02-10 15:10:22 -08005276 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005277 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005278 }
5279
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005280 if (!connection->waitQueue.empty()) {
5281 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5282 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005283 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005284 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005285 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005286 }
5287 }
5288 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005289 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005290 }
5291
5292 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005293 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5294 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005295 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005296 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005297 }
5298
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005299 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005300 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5301 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5302 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005303 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005304 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005305}
5306
Michael Wright3dd60e22019-03-27 22:06:44 +00005307void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5308 const size_t numMonitors = monitors.size();
5309 for (size_t i = 0; i < numMonitors; i++) {
5310 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005311 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005312 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5313 dump += "\n";
5314 }
5315}
5316
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005317class LooperEventCallback : public LooperCallback {
5318public:
5319 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5320 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5321
5322private:
5323 std::function<int(int events)> mCallback;
5324};
5325
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005326Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005327 if (DEBUG_CHANNEL_CREATION) {
5328 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5329 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005330
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005331 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005332 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005333 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005334
5335 if (result) {
5336 return base::Error(result) << "Failed to open input channel pair with name " << name;
5337 }
5338
Michael Wrightd02c5b62014-02-10 15:10:22 -08005339 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005340 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005341 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005342 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005343 sp<Connection> connection =
5344 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005345
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005346 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5347 ALOGE("Created a new connection, but the token %p is already known", token.get());
5348 }
5349 mConnectionsByToken.emplace(token, connection);
5350
5351 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5352 this, std::placeholders::_1, token);
5353
5354 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005355 } // release lock
5356
5357 // Wake the looper because some connections have changed.
5358 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005359 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005360}
5361
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005362Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5363 bool isGestureMonitor,
5364 const std::string& name,
5365 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005366 std::shared_ptr<InputChannel> serverChannel;
5367 std::unique_ptr<InputChannel> clientChannel;
5368 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5369 if (result) {
5370 return base::Error(result) << "Failed to open input channel pair with name " << name;
5371 }
5372
Michael Wright3dd60e22019-03-27 22:06:44 +00005373 { // acquire lock
5374 std::scoped_lock _l(mLock);
5375
5376 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005377 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5378 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005379 }
5380
Garfield Tan15601662020-09-22 15:32:38 -07005381 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005382 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005383 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005384
5385 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5386 ALOGE("Created a new connection, but the token %p is already known", token.get());
5387 }
5388 mConnectionsByToken.emplace(token, connection);
5389 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5390 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005391
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005392 auto& monitorsByDisplay =
5393 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005394 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005395
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005396 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Siarhei Vishniakouc961c742021-05-19 19:16:59 +00005397 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5398 displayId, toString(isGestureMonitor), pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005399 }
Garfield Tan15601662020-09-22 15:32:38 -07005400
Michael Wright3dd60e22019-03-27 22:06:44 +00005401 // Wake the looper because some connections have changed.
5402 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005403 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005404}
5405
Garfield Tan15601662020-09-22 15:32:38 -07005406status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005407 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005408 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005409
Garfield Tan15601662020-09-22 15:32:38 -07005410 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005411 if (status) {
5412 return status;
5413 }
5414 } // release lock
5415
5416 // Wake the poll loop because removing the connection may have changed the current
5417 // synchronization state.
5418 mLooper->wake();
5419 return OK;
5420}
5421
Garfield Tan15601662020-09-22 15:32:38 -07005422status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5423 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005424 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005425 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005426 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005427 return BAD_VALUE;
5428 }
5429
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005430 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005431
Michael Wrightd02c5b62014-02-10 15:10:22 -08005432 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005433 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005434 }
5435
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005436 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005437
5438 nsecs_t currentTime = now();
5439 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5440
5441 connection->status = Connection::STATUS_ZOMBIE;
5442 return OK;
5443}
5444
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005445void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5446 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5447 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005448}
5449
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005450void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005451 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005452 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005453 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005454 std::vector<Monitor>& monitors = it->second;
5455 const size_t numMonitors = monitors.size();
5456 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005457 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005458 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5459 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005460 monitors.erase(monitors.begin() + i);
5461 break;
5462 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005463 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005464 if (monitors.empty()) {
5465 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005466 } else {
5467 ++it;
5468 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005469 }
5470}
5471
Michael Wright3dd60e22019-03-27 22:06:44 +00005472status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5473 { // acquire lock
5474 std::scoped_lock _l(mLock);
5475 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5476
5477 if (!foundDisplayId) {
5478 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5479 return BAD_VALUE;
5480 }
5481 int32_t displayId = foundDisplayId.value();
5482
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005483 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5484 mTouchStatesByDisplay.find(displayId);
5485 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005486 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5487 return BAD_VALUE;
5488 }
5489
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005490 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005491 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005492 std::optional<int32_t> foundDeviceId;
5493 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005494 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005495 requestingChannel = touchedMonitor.monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005496 foundDeviceId = state.deviceId;
5497 }
5498 }
5499 if (!foundDeviceId || !state.down) {
5500 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005501 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005502 return BAD_VALUE;
5503 }
5504 int32_t deviceId = foundDeviceId.value();
5505
5506 // Send cancel events to all the input channels we're stealing from.
5507 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005508 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005509 options.deviceId = deviceId;
5510 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005511 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005512 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005513 std::shared_ptr<InputChannel> channel =
5514 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005515 if (channel != nullptr) {
5516 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005517 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005518 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005519 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005520 canceledWindows += "]";
5521 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5522 canceledWindows.c_str());
5523
Michael Wright3dd60e22019-03-27 22:06:44 +00005524 // Then clear the current touch state so we stop dispatching to them as well.
5525 state.filterNonMonitors();
5526 }
5527 return OK;
5528}
5529
Prabir Pradhan99987712020-11-10 18:43:05 -08005530void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5531 { // acquire lock
5532 std::scoped_lock _l(mLock);
5533 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005534 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005535 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5536 windowHandle != nullptr ? windowHandle->getName().c_str()
5537 : "token without window");
5538 }
5539
Vishnu Nairc519ff72021-01-21 08:23:08 -08005540 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005541 if (focusedToken != windowToken) {
5542 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5543 enabled ? "enable" : "disable");
5544 return;
5545 }
5546
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005547 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08005548 ALOGW("Ignoring request to %s Pointer Capture: "
5549 "window has %s requested pointer capture.",
5550 enabled ? "enable" : "disable", enabled ? "already" : "not");
5551 return;
5552 }
5553
Prabir Pradhan99987712020-11-10 18:43:05 -08005554 setPointerCaptureLocked(enabled);
5555 } // release lock
5556
5557 // Wake the thread to process command entries.
5558 mLooper->wake();
5559}
5560
Michael Wright3dd60e22019-03-27 22:06:44 +00005561std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5562 const sp<IBinder>& token) {
5563 for (const auto& it : mGestureMonitorsByDisplay) {
5564 const std::vector<Monitor>& monitors = it.second;
5565 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005566 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005567 return it.first;
5568 }
5569 }
5570 }
5571 return std::nullopt;
5572}
5573
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005574std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5575 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5576 if (gesturePid.has_value()) {
5577 return gesturePid;
5578 }
5579 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5580}
5581
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005582sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005583 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005584 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005585 }
5586
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005587 for (const auto& [token, connection] : mConnectionsByToken) {
5588 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005589 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005590 }
5591 }
Robert Carr4e670e52018-08-15 13:26:12 -07005592
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005593 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005594}
5595
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005596std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5597 sp<Connection> connection = getConnectionLocked(connectionToken);
5598 if (connection == nullptr) {
5599 return "<nullptr>";
5600 }
5601 return connection->getInputChannelName();
5602}
5603
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005604void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005605 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005606 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005607}
5608
Prabir Pradhancef936d2021-07-21 16:17:52 +00005609void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5610 const sp<Connection>& connection, uint32_t seq,
5611 bool handled, nsecs_t consumeTime) {
5612 // Handle post-event policy actions.
5613 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5614 if (dispatchEntryIt == connection->waitQueue.end()) {
5615 return;
5616 }
5617 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5618 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5619 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5620 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5621 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5622 }
5623 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5624 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5625 connection->inputChannel->getConnectionToken(),
5626 dispatchEntry->deliveryTime, consumeTime, finishTime);
5627 }
5628
5629 bool restartEvent;
5630 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5631 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5632 restartEvent =
5633 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5634 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5635 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5636 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5637 handled);
5638 } else {
5639 restartEvent = false;
5640 }
5641
5642 // Dequeue the event and start the next cycle.
5643 // Because the lock might have been released, it is possible that the
5644 // contents of the wait queue to have been drained, so we need to double-check
5645 // a few things.
5646 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5647 if (dispatchEntryIt != connection->waitQueue.end()) {
5648 dispatchEntry = *dispatchEntryIt;
5649 connection->waitQueue.erase(dispatchEntryIt);
5650 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5651 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5652 if (!connection->responsive) {
5653 connection->responsive = isConnectionResponsive(*connection);
5654 if (connection->responsive) {
5655 // The connection was unresponsive, and now it's responsive.
5656 processConnectionResponsiveLocked(*connection);
5657 }
5658 }
5659 traceWaitQueueLength(*connection);
5660 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
5661 connection->outboundQueue.push_front(dispatchEntry);
5662 traceOutboundQueueLength(*connection);
5663 } else {
5664 releaseDispatchEntry(dispatchEntry);
5665 }
5666 }
5667
5668 // Start the next dispatch cycle for this connection.
5669 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005670}
5671
Prabir Pradhancef936d2021-07-21 16:17:52 +00005672void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5673 const sp<IBinder>& newToken) {
5674 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5675 scoped_unlock unlock(mLock);
5676 mPolicy->notifyFocusChanged(oldToken, newToken);
5677 };
5678 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005679}
5680
Prabir Pradhancef936d2021-07-21 16:17:52 +00005681void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5682 auto command = [this, token, x, y]() REQUIRES(mLock) {
5683 scoped_unlock unlock(mLock);
5684 mPolicy->notifyDropWindow(token, x, y);
5685 };
5686 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005687}
5688
Prabir Pradhancef936d2021-07-21 16:17:52 +00005689void InputDispatcher::sendUntrustedTouchCommandLocked(const std::string& obscuringPackage) {
5690 auto command = [this, obscuringPackage]() REQUIRES(mLock) {
5691 scoped_unlock unlock(mLock);
5692 mPolicy->notifyUntrustedTouch(obscuringPackage);
5693 };
5694 postCommandLocked(std::move(command));
arthurhungf452d0b2021-01-06 00:19:52 +08005695}
5696
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005697void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5698 if (connection == nullptr) {
5699 LOG_ALWAYS_FATAL("Caller must check for nullness");
5700 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005701 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5702 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005703 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005704 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005705 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005706 return;
5707 }
5708 /**
5709 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5710 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5711 * has changed. This could cause newer entries to time out before the already dispatched
5712 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5713 * processes the events linearly. So providing information about the oldest entry seems to be
5714 * most useful.
5715 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005716 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005717 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5718 std::string reason =
5719 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005720 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005721 ns2ms(currentWait),
5722 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005723 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005724 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005725
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005726 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5727
5728 // Stop waking up for events on this connection, it is already unresponsive
5729 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005730}
5731
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005732void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5733 std::string reason =
5734 StringPrintf("%s does not have a focused window", application->getName().c_str());
5735 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005736
Prabir Pradhancef936d2021-07-21 16:17:52 +00005737 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5738 scoped_unlock unlock(mLock);
5739 mPolicy->notifyNoFocusedWindowAnr(application);
5740 };
5741 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005742}
5743
chaviw98318de2021-05-19 16:45:23 -05005744void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005745 const std::string& reason) {
5746 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5747 updateLastAnrStateLocked(windowLabel, reason);
5748}
5749
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005750void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5751 const std::string& reason) {
5752 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005753 updateLastAnrStateLocked(windowLabel, reason);
5754}
5755
5756void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5757 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005758 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005759 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005760 struct tm tm;
5761 localtime_r(&t, &tm);
5762 char timestr[64];
5763 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005764 mLastAnrState.clear();
5765 mLastAnrState += INDENT "ANR:\n";
5766 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005767 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5768 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005769 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005770}
5771
Prabir Pradhancef936d2021-07-21 16:17:52 +00005772void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5773 KeyEntry& entry) {
5774 const KeyEvent event = createKeyEvent(entry);
5775 nsecs_t delay = 0;
5776 { // release lock
5777 scoped_unlock unlock(mLock);
5778 android::base::Timer t;
5779 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5780 entry.policyFlags);
5781 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5782 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5783 std::to_string(t.duration().count()).c_str());
5784 }
5785 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005786
5787 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005788 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005789 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005790 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005791 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005792 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5793 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005794 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005795}
5796
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005797void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005798 auto command = [this, pid, reason = std::move(reason)]() REQUIRES(mLock) {
5799 scoped_unlock unlock(mLock);
5800 mPolicy->notifyMonitorUnresponsive(pid, reason);
5801 };
5802 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005803}
5804
Prabir Pradhancef936d2021-07-21 16:17:52 +00005805void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005806 std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005807 auto command = [this, token, reason = std::move(reason)]() REQUIRES(mLock) {
5808 scoped_unlock unlock(mLock);
5809 mPolicy->notifyWindowUnresponsive(token, reason);
5810 };
5811 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005812}
5813
5814void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005815 auto command = [this, pid]() REQUIRES(mLock) {
5816 scoped_unlock unlock(mLock);
5817 mPolicy->notifyMonitorResponsive(pid);
5818 };
5819 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005820}
5821
Prabir Pradhancef936d2021-07-21 16:17:52 +00005822void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) {
5823 auto command = [this, connectionToken]() REQUIRES(mLock) {
5824 scoped_unlock unlock(mLock);
5825 mPolicy->notifyWindowResponsive(connectionToken);
5826 };
5827 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005828}
5829
5830/**
5831 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5832 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5833 * command entry to the command queue.
5834 */
5835void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5836 std::string reason) {
5837 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5838 if (connection.monitor) {
5839 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5840 reason.c_str());
5841 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5842 if (!pid.has_value()) {
5843 ALOGE("Could not find unresponsive monitor for connection %s",
5844 connection.inputChannel->getName().c_str());
5845 return;
5846 }
5847 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5848 return;
5849 }
5850 // If not a monitor, must be a window
5851 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5852 reason.c_str());
5853 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5854}
5855
5856/**
5857 * Tell the policy that a connection has become responsive so that it can stop ANR.
5858 */
5859void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5860 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5861 if (connection.monitor) {
5862 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5863 if (!pid.has_value()) {
5864 ALOGE("Could not find responsive monitor for connection %s",
5865 connection.inputChannel->getName().c_str());
5866 return;
5867 }
5868 sendMonitorResponsiveCommandLocked(pid.value());
5869 return;
5870 }
5871 // If not a monitor, must be a window
5872 sendWindowResponsiveCommandLocked(connectionToken);
5873}
5874
Prabir Pradhancef936d2021-07-21 16:17:52 +00005875bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005876 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005877 KeyEntry& keyEntry, bool handled) {
5878 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005879 if (!handled) {
5880 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005881 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005882 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005883 return false;
5884 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005885
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005886 // Get the fallback key state.
5887 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005888 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005889 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005890 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005891 connection->inputState.removeFallbackKey(originalKeyCode);
5892 }
5893
5894 if (handled || !dispatchEntry->hasForegroundTarget()) {
5895 // If the application handles the original key for which we previously
5896 // generated a fallback or if the window is not a foreground window,
5897 // then cancel the associated fallback key, if any.
5898 if (fallbackKeyCode != -1) {
5899 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005900 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5901 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
5902 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5903 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
5904 keyEntry.policyFlags);
5905 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005906 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005907 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005908
5909 mLock.unlock();
5910
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005911 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005912 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005913
5914 mLock.lock();
5915
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005916 // Cancel the fallback key.
5917 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005918 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005919 "application handled the original non-fallback key "
5920 "or is no longer a foreground target, "
5921 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005922 options.keyCode = fallbackKeyCode;
5923 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005924 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005925 connection->inputState.removeFallbackKey(originalKeyCode);
5926 }
5927 } else {
5928 // If the application did not handle a non-fallback key, first check
5929 // that we are in a good state to perform unhandled key event processing
5930 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005931 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005932 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005933 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5934 ALOGD("Unhandled key event: Skipping unhandled key event processing "
5935 "since this is not an initial down. "
5936 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5937 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5938 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005939 return false;
5940 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005941
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005942 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005943 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5944 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
5945 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5946 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5947 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005948 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005949
5950 mLock.unlock();
5951
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005952 bool fallback =
5953 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005954 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005955
5956 mLock.lock();
5957
5958 if (connection->status != Connection::STATUS_NORMAL) {
5959 connection->inputState.removeFallbackKey(originalKeyCode);
5960 return false;
5961 }
5962
5963 // Latch the fallback keycode for this key on an initial down.
5964 // The fallback keycode cannot change at any other point in the lifecycle.
5965 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005966 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005967 fallbackKeyCode = event.getKeyCode();
5968 } else {
5969 fallbackKeyCode = AKEYCODE_UNKNOWN;
5970 }
5971 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5972 }
5973
5974 ALOG_ASSERT(fallbackKeyCode != -1);
5975
5976 // Cancel the fallback key if the policy decides not to send it anymore.
5977 // We will continue to dispatch the key to the policy but we will no
5978 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005979 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5980 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005981 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5982 if (fallback) {
5983 ALOGD("Unhandled key event: Policy requested to send key %d"
5984 "as a fallback for %d, but on the DOWN it had requested "
5985 "to send %d instead. Fallback canceled.",
5986 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
5987 } else {
5988 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
5989 "but on the DOWN it had requested to send %d. "
5990 "Fallback canceled.",
5991 originalKeyCode, fallbackKeyCode);
5992 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005993 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005994
5995 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5996 "canceling fallback, policy no longer desires it");
5997 options.keyCode = fallbackKeyCode;
5998 synthesizeCancelationEventsForConnectionLocked(connection, options);
5999
6000 fallback = false;
6001 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006002 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006003 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006004 }
6005 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006006
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006007 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6008 {
6009 std::string msg;
6010 const KeyedVector<int32_t, int32_t>& fallbackKeys =
6011 connection->inputState.getFallbackKeys();
6012 for (size_t i = 0; i < fallbackKeys.size(); i++) {
6013 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
6014 }
6015 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6016 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006017 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006018 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006019
6020 if (fallback) {
6021 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006022 keyEntry.eventTime = event.getEventTime();
6023 keyEntry.deviceId = event.getDeviceId();
6024 keyEntry.source = event.getSource();
6025 keyEntry.displayId = event.getDisplayId();
6026 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
6027 keyEntry.keyCode = fallbackKeyCode;
6028 keyEntry.scanCode = event.getScanCode();
6029 keyEntry.metaState = event.getMetaState();
6030 keyEntry.repeatCount = event.getRepeatCount();
6031 keyEntry.downTime = event.getDownTime();
6032 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006033
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006034 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6035 ALOGD("Unhandled key event: Dispatching fallback key. "
6036 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
6037 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
6038 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006039 return true; // restart the event
6040 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006041 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6042 ALOGD("Unhandled key event: No fallback key.");
6043 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006044
6045 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006046 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006047 }
6048 }
6049 return false;
6050}
6051
Prabir Pradhancef936d2021-07-21 16:17:52 +00006052bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006053 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006054 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006055 return false;
6056}
6057
Michael Wrightd02c5b62014-02-10 15:10:22 -08006058void InputDispatcher::traceInboundQueueLengthLocked() {
6059 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006060 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006061 }
6062}
6063
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006064void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006065 if (ATRACE_ENABLED()) {
6066 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006067 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6068 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006069 }
6070}
6071
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006072void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006073 if (ATRACE_ENABLED()) {
6074 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006075 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6076 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006077 }
6078}
6079
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006080void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006081 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006082
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006083 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006084 dumpDispatchStateLocked(dump);
6085
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006086 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006087 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006088 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006089 }
6090}
6091
6092void InputDispatcher::monitor() {
6093 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006094 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006095 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006096 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006097}
6098
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006099/**
6100 * Wake up the dispatcher and wait until it processes all events and commands.
6101 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6102 * this method can be safely called from any thread, as long as you've ensured that
6103 * the work you are interested in completing has already been queued.
6104 */
6105bool InputDispatcher::waitForIdle() {
6106 /**
6107 * Timeout should represent the longest possible time that a device might spend processing
6108 * events and commands.
6109 */
6110 constexpr std::chrono::duration TIMEOUT = 100ms;
6111 std::unique_lock lock(mLock);
6112 mLooper->wake();
6113 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6114 return result == std::cv_status::no_timeout;
6115}
6116
Vishnu Naire798b472020-07-23 13:52:21 -07006117/**
6118 * Sets focus to the window identified by the token. This must be called
6119 * after updating any input window handles.
6120 *
6121 * Params:
6122 * request.token - input channel token used to identify the window that should gain focus.
6123 * request.focusedToken - the token that the caller expects currently to be focused. If the
6124 * specified token does not match the currently focused window, this request will be dropped.
6125 * If the specified focused token matches the currently focused window, the call will succeed.
6126 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6127 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6128 * when requesting the focus change. This determines which request gets
6129 * precedence if there is a focus change request from another source such as pointer down.
6130 */
Vishnu Nair958da932020-08-21 17:12:37 -07006131void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6132 { // acquire lock
6133 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006134 std::optional<FocusResolver::FocusChanges> changes =
6135 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6136 if (changes) {
6137 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006138 }
6139 } // release lock
6140 // Wake up poll loop since it may need to make new input dispatching choices.
6141 mLooper->wake();
6142}
6143
Vishnu Nairc519ff72021-01-21 08:23:08 -08006144void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6145 if (changes.oldFocus) {
6146 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006147 if (focusedInputChannel) {
6148 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6149 "focus left window");
6150 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006151 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006152 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006153 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006154 if (changes.newFocus) {
6155 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006156 }
6157
Prabir Pradhan99987712020-11-10 18:43:05 -08006158 // If a window has pointer capture, then it must have focus. We need to ensure that this
6159 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6160 // If the window loses focus before it loses pointer capture, then the window can be in a state
6161 // where it has pointer capture but not focus, violating the contract. Therefore we must
6162 // dispatch the pointer capture event before the focus event. Since focus events are added to
6163 // the front of the queue (above), we add the pointer capture event to the front of the queue
6164 // after the focus events are added. This ensures the pointer capture event ends up at the
6165 // front.
6166 disablePointerCaptureForcedLocked();
6167
Vishnu Nairc519ff72021-01-21 08:23:08 -08006168 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006169 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006170 }
6171}
Vishnu Nair958da932020-08-21 17:12:37 -07006172
Prabir Pradhan99987712020-11-10 18:43:05 -08006173void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006174 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006175 return;
6176 }
6177
6178 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6179
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006180 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006181 setPointerCaptureLocked(false);
6182 }
6183
6184 if (!mWindowTokenWithPointerCapture) {
6185 // No need to send capture changes because no window has capture.
6186 return;
6187 }
6188
6189 if (mPendingEvent != nullptr) {
6190 // Move the pending event to the front of the queue. This will give the chance
6191 // for the pending event to be dropped if it is a captured event.
6192 mInboundQueue.push_front(mPendingEvent);
6193 mPendingEvent = nullptr;
6194 }
6195
6196 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006197 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006198 mInboundQueue.push_front(std::move(entry));
6199}
6200
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006201void InputDispatcher::setPointerCaptureLocked(bool enable) {
6202 mCurrentPointerCaptureRequest.enable = enable;
6203 mCurrentPointerCaptureRequest.seq++;
6204 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006205 scoped_unlock unlock(mLock);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006206 mPolicy->setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006207 };
6208 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006209}
6210
Vishnu Nair599f1412021-06-21 10:39:58 -07006211void InputDispatcher::displayRemoved(int32_t displayId) {
6212 { // acquire lock
6213 std::scoped_lock _l(mLock);
6214 // Set an empty list to remove all handles from the specific display.
6215 setInputWindowsLocked(/* window handles */ {}, displayId);
6216 setFocusedApplicationLocked(displayId, nullptr);
6217 // Call focus resolver to clean up stale requests. This must be called after input windows
6218 // have been removed for the removed display.
6219 mFocusResolver.displayRemoved(displayId);
6220 } // release lock
6221
6222 // Wake up poll loop since it may need to make new input dispatching choices.
6223 mLooper->wake();
6224}
6225
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006226void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
6227 const std::vector<DisplayInfo>& displayInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006228 // The listener sends the windows as a flattened array. Separate the windows by display for
6229 // more convenient parsing.
6230 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
chaviw15fab6f2021-06-07 14:15:52 -05006231 for (const auto& info : windowInfos) {
6232 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
6233 handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
6234 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006235
6236 { // acquire lock
6237 std::scoped_lock _l(mLock);
6238 mDisplayInfos.clear();
6239 for (const auto& displayInfo : displayInfos) {
6240 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6241 }
6242
6243 for (const auto& [displayId, handles] : handlesPerDisplay) {
6244 setInputWindowsLocked(handles, displayId);
6245 }
6246 }
6247 // Wake up poll loop since it may need to make new input dispatching choices.
6248 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006249}
6250
Vishnu Nair062a8672021-09-03 16:07:44 -07006251bool InputDispatcher::shouldDropInput(
6252 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
6253 if (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT) ||
6254 (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT_IF_OBSCURED) &&
6255 isWindowObscuredLocked(windowHandle))) {
6256 ALOGW("Dropping %s event targeting %s as requested by input feature %s on display "
6257 "%" PRId32 ".",
6258 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
6259 windowHandle->getInfo()->inputFeatures.string().c_str(),
6260 windowHandle->getInfo()->displayId);
6261 return true;
6262 }
6263 return false;
6264}
6265
Garfield Tane84e6f92019-08-29 17:28:41 -07006266} // namespace android::inputdispatcher