blob: da3e237e3e706eeaf618970b80faa730eff2c958 [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,
Evan Rosky84f07f02021-04-16 10:42:42 -0700349 1.0f /*globalScaleFactor*/,
Evan Rosky09576692021-07-01 12:22:09 -0700350 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700351 inputTarget.displaySize);
yunho.shinf4a80b82020-11-16 21:13:57 +0900352 }
353 }
354
chaviw1ff3d1e2020-07-01 15:53:47 -0700355 if (inputTarget.useDefaultPointerTransform()) {
356 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700357 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700358 inputTarget.globalScaleFactor,
Evan Rosky09576692021-07-01 12:22:09 -0700359 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700360 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000361 }
362
363 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
364 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
365
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700366 std::vector<PointerCoords> pointerCoords;
367 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000368
369 // Use the first pointer information to normalize all other pointers. This could be any pointer
370 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700371 // uses the transform for the normalized pointer.
372 const ui::Transform& firstPointerTransform =
373 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
374 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000375
376 // Iterate through all pointers in the event to normalize against the first.
377 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
378 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
379 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700380 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000381
382 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700383 // First, apply the current pointer's transform to update the coordinates into
384 // window space.
385 pointerCoords[pointerIndex].transform(currTransform);
386 // Next, apply the inverse transform of the normalized coordinates so the
387 // current coordinates are transformed into the normalized coordinate space.
388 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000389 }
390
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700391 std::unique_ptr<MotionEntry> combinedMotionEntry =
392 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
393 motionEntry.deviceId, motionEntry.source,
394 motionEntry.displayId, motionEntry.policyFlags,
395 motionEntry.action, motionEntry.actionButton,
396 motionEntry.flags, motionEntry.metaState,
397 motionEntry.buttonState, motionEntry.classification,
398 motionEntry.edgeFlags, motionEntry.xPrecision,
399 motionEntry.yPrecision, motionEntry.xCursorPosition,
400 motionEntry.yCursorPosition, motionEntry.downTime,
401 motionEntry.pointerCount, motionEntry.pointerProperties,
402 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000403
404 if (motionEntry.injectionState) {
405 combinedMotionEntry->injectionState = motionEntry.injectionState;
406 combinedMotionEntry->injectionState->refCount += 1;
407 }
408
409 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700410 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Evan Rosky84f07f02021-04-16 10:42:42 -0700411 firstPointerTransform, inputTarget.globalScaleFactor,
Evan Rosky09576692021-07-01 12:22:09 -0700412 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700413 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000414 return dispatchEntry;
415}
416
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000417void addGestureMonitors(const std::vector<Monitor>& monitors,
418 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
419 float yOffset = 0) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700420 if (monitors.empty()) {
421 return;
422 }
423 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
424 for (const Monitor& monitor : monitors) {
425 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
426 }
427}
428
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000429status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
430 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700431 std::unique_ptr<InputChannel> uniqueServerChannel;
432 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
433
434 serverChannel = std::move(uniqueServerChannel);
435 return result;
436}
437
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500438template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000439bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500440 if (lhs == nullptr && rhs == nullptr) {
441 return true;
442 }
443 if (lhs == nullptr || rhs == nullptr) {
444 return false;
445 }
446 return *lhs == *rhs;
447}
448
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000449sp<IPlatformCompatNative> getCompatService() {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000450 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
451 if (service == nullptr) {
452 ALOGE("Failed to link to compat service");
453 return nullptr;
454 }
455 return interface_cast<IPlatformCompatNative>(service);
456}
457
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000458KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000459 KeyEvent event;
460 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
461 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
462 entry.repeatCount, entry.downTime, entry.eventTime);
463 return event;
464}
465
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000466std::optional<int32_t> findMonitorPidByToken(
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000467 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
468 const sp<IBinder>& token) {
469 for (const auto& it : monitorsByDisplay) {
470 const std::vector<Monitor>& monitors = it.second;
471 for (const Monitor& monitor : monitors) {
472 if (monitor.inputChannel->getConnectionToken() == token) {
473 return monitor.pid;
474 }
475 }
476 }
477 return std::nullopt;
478}
479
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000480bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000481 // Do not keep track of gesture monitors. They receive every event and would disproportionately
482 // affect the statistics.
483 if (connection.monitor) {
484 return false;
485 }
486 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
487 if (!connection.responsive) {
488 return false;
489 }
490 return true;
491}
492
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000493bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000494 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
495 const int32_t& inputEventId = eventEntry.id;
496 if (inputEventId != dispatchEntry.resolvedEventId) {
497 // Event was transmuted
498 return false;
499 }
500 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
501 return false;
502 }
503 // Only track latency for events that originated from hardware
504 if (eventEntry.isSynthesized()) {
505 return false;
506 }
507 const EventEntry::Type& inputEventEntryType = eventEntry.type;
508 if (inputEventEntryType == EventEntry::Type::KEY) {
509 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
510 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
511 return false;
512 }
513 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
514 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
515 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
516 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
517 return false;
518 }
519 } else {
520 // Not a key or a motion
521 return false;
522 }
523 if (!shouldReportMetricsForConnection(connection)) {
524 return false;
525 }
526 return true;
527}
528
Prabir Pradhancef936d2021-07-21 16:17:52 +0000529/**
530 * Connection is responsive if it has no events in the waitQueue that are older than the
531 * current time.
532 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000533bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000534 const nsecs_t currentTime = now();
535 for (const DispatchEntry* entry : connection.waitQueue) {
536 if (entry->timeoutTime < currentTime) {
537 return false;
538 }
539 }
540 return true;
541}
542
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000543} // namespace
544
Michael Wrightd02c5b62014-02-10 15:10:22 -0800545// --- InputDispatcher ---
546
Garfield Tan00f511d2019-06-12 16:55:40 -0700547InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
548 : mPolicy(policy),
549 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700550 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800551 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700552 mAppSwitchSawKeyDown(false),
553 mAppSwitchDueTime(LONG_LONG_MAX),
554 mNextUnblockedEvent(nullptr),
555 mDispatchEnabled(false),
556 mDispatchFrozen(false),
557 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800558 // mInTouchMode will be initialized by the WindowManager to the default device config.
559 // To avoid leaking stack in case that call never comes, and for tests,
560 // initialize it here anyways.
561 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100562 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000563 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800564 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000565 mLatencyAggregator(),
566 mLatencyTracker(&mLatencyAggregator),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000567 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800568 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800569 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800570
Yi Kong9b14ac62018-07-17 13:48:38 -0700571 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800572
573 policy->getDispatcherConfiguration(&mConfig);
574}
575
576InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000577 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800578
Prabir Pradhancef936d2021-07-21 16:17:52 +0000579 resetKeyRepeatLocked();
580 releasePendingEventLocked();
581 drainInboundQueueLocked();
582 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800583
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000584 while (!mConnectionsByToken.empty()) {
585 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000586 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
587 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800588 }
589}
590
chaviw15fab6f2021-06-07 14:15:52 -0500591void InputDispatcher::onFirstRef() {
592 SurfaceComposerClient::getDefault()->addWindowInfosListener(this);
593}
594
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700595status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700596 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700597 return ALREADY_EXISTS;
598 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700599 mThread = std::make_unique<InputThread>(
600 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
601 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700602}
603
604status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700605 if (mThread && mThread->isCallingThread()) {
606 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700607 return INVALID_OPERATION;
608 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700609 mThread.reset();
610 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700611}
612
Michael Wrightd02c5b62014-02-10 15:10:22 -0800613void InputDispatcher::dispatchOnce() {
614 nsecs_t nextWakeupTime = LONG_LONG_MAX;
615 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800616 std::scoped_lock _l(mLock);
617 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800618
619 // Run a dispatch loop if there are no pending commands.
620 // The dispatch loop might enqueue commands to run afterwards.
621 if (!haveCommandsLocked()) {
622 dispatchOnceInnerLocked(&nextWakeupTime);
623 }
624
625 // Run all pending commands if there are any.
626 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000627 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800628 nextWakeupTime = LONG_LONG_MIN;
629 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800630
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700631 // If we are still waiting for ack on some events,
632 // we might have to wake up earlier to check if an app is anr'ing.
633 const nsecs_t nextAnrCheck = processAnrsLocked();
634 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
635
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800636 // We are about to enter an infinitely long sleep, because we have no commands or
637 // pending or queued events
638 if (nextWakeupTime == LONG_LONG_MAX) {
639 mDispatcherEnteredIdle.notify_all();
640 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800641 } // release lock
642
643 // Wait for callback or timeout or wake. (make sure we round up, not down)
644 nsecs_t currentTime = now();
645 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
646 mLooper->pollOnce(timeoutMillis);
647}
648
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700649/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500650 * Raise ANR if there is no focused window.
651 * Before the ANR is raised, do a final state check:
652 * 1. The currently focused application must be the same one we are waiting for.
653 * 2. Ensure we still don't have a focused window.
654 */
655void InputDispatcher::processNoFocusedWindowAnrLocked() {
656 // Check if the application that we are waiting for is still focused.
657 std::shared_ptr<InputApplicationHandle> focusedApplication =
658 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
659 if (focusedApplication == nullptr ||
660 focusedApplication->getApplicationToken() !=
661 mAwaitedFocusedApplication->getApplicationToken()) {
662 // Unexpected because we should have reset the ANR timer when focused application changed
663 ALOGE("Waited for a focused window, but focused application has already changed to %s",
664 focusedApplication->getName().c_str());
665 return; // The focused application has changed.
666 }
667
chaviw98318de2021-05-19 16:45:23 -0500668 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500669 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
670 if (focusedWindowHandle != nullptr) {
671 return; // We now have a focused window. No need for ANR.
672 }
673 onAnrLocked(mAwaitedFocusedApplication);
674}
675
676/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700677 * Check if any of the connections' wait queues have events that are too old.
678 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
679 * Return the time at which we should wake up next.
680 */
681nsecs_t InputDispatcher::processAnrsLocked() {
682 const nsecs_t currentTime = now();
683 nsecs_t nextAnrCheck = LONG_LONG_MAX;
684 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
685 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
686 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500687 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700688 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500689 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700690 return LONG_LONG_MIN;
691 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500692 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700693 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
694 }
695 }
696
697 // Check if any connection ANRs are due
698 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
699 if (currentTime < nextAnrCheck) { // most likely scenario
700 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
701 }
702
703 // If we reached here, we have an unresponsive connection.
704 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
705 if (connection == nullptr) {
706 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
707 return nextAnrCheck;
708 }
709 connection->responsive = false;
710 // Stop waking up for this unresponsive connection
711 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000712 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700713 return LONG_LONG_MIN;
714}
715
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500716std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
chaviw98318de2021-05-19 16:45:23 -0500717 sp<WindowInfoHandle> window = getWindowHandleLocked(token);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700718 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500719 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700720 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500721 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700722}
723
Michael Wrightd02c5b62014-02-10 15:10:22 -0800724void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
725 nsecs_t currentTime = now();
726
Jeff Browndc5992e2014-04-11 01:27:26 -0700727 // Reset the key repeat timer whenever normal dispatch is suspended while the
728 // device is in a non-interactive state. This is to ensure that we abort a key
729 // repeat if the device is just coming out of sleep.
730 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800731 resetKeyRepeatLocked();
732 }
733
734 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
735 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100736 if (DEBUG_FOCUS) {
737 ALOGD("Dispatch frozen. Waiting some more.");
738 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800739 return;
740 }
741
742 // Optimize latency of app switches.
743 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
744 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
745 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
746 if (mAppSwitchDueTime < *nextWakeupTime) {
747 *nextWakeupTime = mAppSwitchDueTime;
748 }
749
750 // Ready to start a new event.
751 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700752 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700753 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800754 if (isAppSwitchDue) {
755 // The inbound queue is empty so the app switch key we were waiting
756 // for will never arrive. Stop waiting for it.
757 resetPendingAppSwitchLocked(false);
758 isAppSwitchDue = false;
759 }
760
761 // Synthesize a key repeat if appropriate.
762 if (mKeyRepeatState.lastKeyEntry) {
763 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
764 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
765 } else {
766 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
767 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
768 }
769 }
770 }
771
772 // Nothing to do if there is no pending event.
773 if (!mPendingEvent) {
774 return;
775 }
776 } else {
777 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700778 mPendingEvent = mInboundQueue.front();
779 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800780 traceInboundQueueLengthLocked();
781 }
782
783 // Poke user activity for this event.
784 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700785 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800786 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800787 }
788
789 // Now we have an event to dispatch.
790 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700791 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800792 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700793 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800794 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700795 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800796 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700797 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800798 }
799
800 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700801 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800802 }
803
804 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700805 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700806 const ConfigurationChangedEntry& typedEntry =
807 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700808 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700809 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700810 break;
811 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800812
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700813 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700814 const DeviceResetEntry& typedEntry =
815 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700816 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700817 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700818 break;
819 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800820
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100821 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700822 std::shared_ptr<FocusEntry> typedEntry =
823 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100824 dispatchFocusLocked(currentTime, typedEntry);
825 done = true;
826 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
827 break;
828 }
829
Antonio Kantek7242d8b2021-08-05 16:07:20 -0700830 case EventEntry::Type::TOUCH_MODE_CHANGED: {
831 const auto typedEntry = std::static_pointer_cast<TouchModeEntry>(mPendingEvent);
832 dispatchTouchModeChangeLocked(currentTime, typedEntry);
833 done = true;
834 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
835 break;
836 }
837
Prabir Pradhan99987712020-11-10 18:43:05 -0800838 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
839 const auto typedEntry =
840 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
841 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
842 done = true;
843 break;
844 }
845
arthurhungb89ccb02020-12-30 16:19:01 +0800846 case EventEntry::Type::DRAG: {
847 std::shared_ptr<DragEntry> typedEntry =
848 std::static_pointer_cast<DragEntry>(mPendingEvent);
849 dispatchDragLocked(currentTime, typedEntry);
850 done = true;
851 break;
852 }
853
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700854 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700855 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700856 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700857 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700858 resetPendingAppSwitchLocked(true);
859 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700860 } else if (dropReason == DropReason::NOT_DROPPED) {
861 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700862 }
863 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700864 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700865 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700866 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700867 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
868 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700869 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700870 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700871 break;
872 }
873
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700874 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700875 std::shared_ptr<MotionEntry> motionEntry =
876 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700877 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
878 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800879 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700880 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700881 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700882 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700883 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
884 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700885 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700886 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700887 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800888 }
Chris Yef59a2f42020-10-16 12:55:26 -0700889
890 case EventEntry::Type::SENSOR: {
891 std::shared_ptr<SensorEntry> sensorEntry =
892 std::static_pointer_cast<SensorEntry>(mPendingEvent);
893 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
894 dropReason = DropReason::APP_SWITCH;
895 }
896 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
897 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
898 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
899 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
900 dropReason = DropReason::STALE;
901 }
902 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
903 done = true;
904 break;
905 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800906 }
907
908 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700909 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700910 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800911 }
Michael Wright3a981722015-06-10 15:26:13 +0100912 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800913
914 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700915 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800916 }
917}
918
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700919/**
920 * Return true if the events preceding this incoming motion event should be dropped
921 * Return false otherwise (the default behaviour)
922 */
923bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700924 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700925 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700926
927 // Optimize case where the current application is unresponsive and the user
928 // decides to touch a window in a different application.
929 // If the application takes too long to catch up then we drop all events preceding
930 // the touch into the other window.
931 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700932 int32_t displayId = motionEntry.displayId;
933 int32_t x = static_cast<int32_t>(
934 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
935 int32_t y = static_cast<int32_t>(
936 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
chaviw98318de2021-05-19 16:45:23 -0500937 sp<WindowInfoHandle> touchedWindowHandle =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700938 findTouchedWindowAtLocked(displayId, x, y, nullptr);
939 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700940 touchedWindowHandle->getApplicationToken() !=
941 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700942 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700943 ALOGI("Pruning input queue because user touched a different application while waiting "
944 "for %s",
945 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700946 return true;
947 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700948
949 // Alternatively, maybe there's a gesture monitor that could handle this event
Siarhei Vishniakou64452932020-11-06 17:51:32 -0600950 std::vector<TouchedMonitor> gestureMonitors = findTouchedGestureMonitorsLocked(displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700951 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
952 sp<Connection> connection =
953 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000954 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700955 // This monitor could take more input. Drop all events preceding this
956 // event, so that gesture monitor could get a chance to receive the stream
957 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
958 "responsive gesture monitor that may handle the event",
959 mAwaitedFocusedApplication->getName().c_str());
960 return true;
961 }
962 }
963 }
964
965 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
966 // yet been processed by some connections, the dispatcher will wait for these motion
967 // events to be processed before dispatching the key event. This is because these motion events
968 // may cause a new window to be launched, which the user might expect to receive focus.
969 // To prevent waiting forever for such events, just send the key to the currently focused window
970 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
971 ALOGD("Received a new pointer down event, stop waiting for events to process and "
972 "just send the pending key event to the focused window.");
973 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700974 }
975 return false;
976}
977
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700978bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700979 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700980 mInboundQueue.push_back(std::move(newEntry));
981 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800982 traceInboundQueueLengthLocked();
983
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700984 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700985 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700986 // Optimize app switch latency.
987 // If the application takes too long to catch up then we drop all events preceding
988 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700989 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700990 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700991 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700992 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700993 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700994 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000995 if (DEBUG_APP_SWITCH) {
996 ALOGD("App switch is pending!");
997 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700998 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700999 mAppSwitchSawKeyDown = false;
1000 needWake = true;
1001 }
1002 }
1003 }
1004 break;
1005 }
1006
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001007 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001008 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
1009 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001010 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001011 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001012 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001013 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001014 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001015 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1016 break;
1017 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001018 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001019 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001020 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001021 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001022 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1023 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001024 // nothing to do
1025 break;
1026 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001027 }
1028
1029 return needWake;
1030}
1031
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001032void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001033 // Do not store sensor event in recent queue to avoid flooding the queue.
1034 if (entry->type != EventEntry::Type::SENSOR) {
1035 mRecentQueue.push_back(entry);
1036 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001037 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001038 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001039 }
1040}
1041
chaviw98318de2021-05-19 16:45:23 -05001042sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1043 int32_t y, TouchState* touchState,
1044 bool addOutsideTargets,
1045 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001046 if (addOutsideTargets && touchState == nullptr) {
1047 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001048 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001049 // Traverse windows from front to back to find touched window.
chaviw98318de2021-05-19 16:45:23 -05001050 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
1051 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001052 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001053 continue;
1054 }
chaviw98318de2021-05-19 16:45:23 -05001055 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001056 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +01001057 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001058
1059 if (windowInfo->visible) {
chaviw98318de2021-05-19 16:45:23 -05001060 if (!flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
1061 bool isTouchModal = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
1062 !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001063 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
1064 // Found window.
1065 return windowHandle;
1066 }
1067 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001068
chaviw98318de2021-05-19 16:45:23 -05001069 if (addOutsideTargets && flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001070 touchState->addOrUpdateWindow(windowHandle,
1071 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1072 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001073 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001074 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001075 }
1076 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001077 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001078}
1079
Garfield Tane84e6f92019-08-29 17:28:41 -07001080std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001081 int32_t displayId) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00001082 std::vector<TouchedMonitor> touchedMonitors;
1083
1084 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
1085 addGestureMonitors(monitors, touchedMonitors);
Michael Wright3dd60e22019-03-27 22:06:44 +00001086 return touchedMonitors;
1087}
1088
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001089void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001090 const char* reason;
1091 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001092 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001093 if (DEBUG_INBOUND_EVENT_DETAILS) {
1094 ALOGD("Dropped event because policy consumed it.");
1095 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001096 reason = "inbound event was dropped because the policy consumed it";
1097 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001098 case DropReason::DISABLED:
1099 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001100 ALOGI("Dropped event because input dispatch is disabled.");
1101 }
1102 reason = "inbound event was dropped because input dispatch is disabled";
1103 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001104 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001105 ALOGI("Dropped event because of pending overdue app switch.");
1106 reason = "inbound event was dropped because of pending overdue app switch";
1107 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001108 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001109 ALOGI("Dropped event because the current application is not responding and the user "
1110 "has started interacting with a different application.");
1111 reason = "inbound event was dropped because the current application is not responding "
1112 "and the user has started interacting with a different application";
1113 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001114 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001115 ALOGI("Dropped event because it is stale.");
1116 reason = "inbound event was dropped because it is stale";
1117 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001118 case DropReason::NO_POINTER_CAPTURE:
1119 ALOGI("Dropped event because there is no window with Pointer Capture.");
1120 reason = "inbound event was dropped because there is no window with Pointer Capture";
1121 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001122 case DropReason::NOT_DROPPED: {
1123 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001124 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001125 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001126 }
1127
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001128 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001129 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1131 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001132 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001133 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001134 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001135 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1136 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001137 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1138 synthesizeCancelationEventsForAllConnectionsLocked(options);
1139 } else {
1140 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1141 synthesizeCancelationEventsForAllConnectionsLocked(options);
1142 }
1143 break;
1144 }
Chris Yef59a2f42020-10-16 12:55:26 -07001145 case EventEntry::Type::SENSOR: {
1146 break;
1147 }
arthurhungb89ccb02020-12-30 16:19:01 +08001148 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1149 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001150 break;
1151 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001152 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001153 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001154 case EventEntry::Type::CONFIGURATION_CHANGED:
1155 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001156 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001157 break;
1158 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001159 }
1160}
1161
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001162static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001163 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1164 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001165}
1166
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001167bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1168 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1169 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1170 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001171}
1172
1173bool InputDispatcher::isAppSwitchPendingLocked() {
1174 return mAppSwitchDueTime != LONG_LONG_MAX;
1175}
1176
1177void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1178 mAppSwitchDueTime = LONG_LONG_MAX;
1179
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001180 if (DEBUG_APP_SWITCH) {
1181 if (handled) {
1182 ALOGD("App switch has arrived.");
1183 } else {
1184 ALOGD("App switch was abandoned.");
1185 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001186 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001187}
1188
Michael Wrightd02c5b62014-02-10 15:10:22 -08001189bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001190 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001191}
1192
Prabir Pradhancef936d2021-07-21 16:17:52 +00001193bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001194 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001195 return false;
1196 }
1197
1198 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001199 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001200 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001201 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1202 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001203 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001204 return true;
1205}
1206
Prabir Pradhancef936d2021-07-21 16:17:52 +00001207void InputDispatcher::postCommandLocked(Command&& command) {
1208 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001209}
1210
1211void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001212 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001213 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001214 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001215 releaseInboundEventLocked(entry);
1216 }
1217 traceInboundQueueLengthLocked();
1218}
1219
1220void InputDispatcher::releasePendingEventLocked() {
1221 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001222 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001223 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001224 }
1225}
1226
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001227void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001228 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001229 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001230 if (DEBUG_DISPATCH_CYCLE) {
1231 ALOGD("Injected inbound event was dropped.");
1232 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001233 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001234 }
1235 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001236 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001237 }
1238 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001239}
1240
1241void InputDispatcher::resetKeyRepeatLocked() {
1242 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001243 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001244 }
1245}
1246
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001247std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1248 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001249
Michael Wright2e732952014-09-24 13:26:59 -07001250 uint32_t policyFlags = entry->policyFlags &
1251 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001252
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001253 std::shared_ptr<KeyEntry> newEntry =
1254 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1255 entry->source, entry->displayId, policyFlags, entry->action,
1256 entry->flags, entry->keyCode, entry->scanCode,
1257 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001258
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001259 newEntry->syntheticRepeat = true;
1260 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001261 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001262 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001263}
1264
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001265bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001266 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001267 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1268 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1269 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001270
1271 // Reset key repeating in case a keyboard device was added or removed or something.
1272 resetKeyRepeatLocked();
1273
1274 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001275 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1276 scoped_unlock unlock(mLock);
1277 mPolicy->notifyConfigurationChanged(eventTime);
1278 };
1279 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001280 return true;
1281}
1282
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001283bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1284 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001285 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1286 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1287 entry.deviceId);
1288 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001289
liushenxiang42232912021-05-21 20:24:09 +08001290 // Reset key repeating in case a keyboard device was disabled or enabled.
1291 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1292 resetKeyRepeatLocked();
1293 }
1294
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001295 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001296 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001297 synthesizeCancelationEventsForAllConnectionsLocked(options);
1298 return true;
1299}
1300
Vishnu Nairad321cd2020-08-20 16:40:21 -07001301void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001302 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001303 if (mPendingEvent != nullptr) {
1304 // Move the pending event to the front of the queue. This will give the chance
1305 // for the pending event to get dispatched to the newly focused window
1306 mInboundQueue.push_front(mPendingEvent);
1307 mPendingEvent = nullptr;
1308 }
1309
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001310 std::unique_ptr<FocusEntry> focusEntry =
1311 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1312 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001313
1314 // This event should go to the front of the queue, but behind all other focus events
1315 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001316 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001317 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001318 [](const std::shared_ptr<EventEntry>& event) {
1319 return event->type == EventEntry::Type::FOCUS;
1320 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001321
1322 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001323 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001324}
1325
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001326void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001327 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001328 if (channel == nullptr) {
1329 return; // Window has gone away
1330 }
1331 InputTarget target;
1332 target.inputChannel = channel;
1333 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1334 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001335 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1336 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001337 std::string reason = std::string("reason=").append(entry->reason);
1338 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001339 dispatchEventLocked(currentTime, entry, {target});
1340}
1341
Prabir Pradhan99987712020-11-10 18:43:05 -08001342void InputDispatcher::dispatchPointerCaptureChangedLocked(
1343 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1344 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001345 dropReason = DropReason::NOT_DROPPED;
1346
Prabir Pradhan99987712020-11-10 18:43:05 -08001347 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001348 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001349
1350 if (entry->pointerCaptureRequest.enable) {
1351 // Enable Pointer Capture.
1352 if (haveWindowWithPointerCapture &&
1353 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1354 LOG_ALWAYS_FATAL("This request to enable Pointer Capture has already been dispatched "
1355 "to the window.");
1356 }
1357 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001358 // This can happen if a window requests capture and immediately releases capture.
1359 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001360 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001361 return;
1362 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001363 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1364 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1365 return;
1366 }
1367
Vishnu Nairc519ff72021-01-21 08:23:08 -08001368 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001369 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1370 mWindowTokenWithPointerCapture = token;
1371 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001372 // Disable Pointer Capture.
1373 // We do not check if the sequence number matches for requests to disable Pointer Capture
1374 // for two reasons:
1375 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1376 // to disable capture with the same sequence number: one generated by
1377 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1378 // Capture being disabled in InputReader.
1379 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1380 // actual Pointer Capture state that affects events being generated by input devices is
1381 // in InputReader.
1382 if (!haveWindowWithPointerCapture) {
1383 // Pointer capture was already forcefully disabled because of focus change.
1384 dropReason = DropReason::NOT_DROPPED;
1385 return;
1386 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001387 token = mWindowTokenWithPointerCapture;
1388 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001389 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001390 setPointerCaptureLocked(false);
1391 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001392 }
1393
1394 auto channel = getInputChannelLocked(token);
1395 if (channel == nullptr) {
1396 // Window has gone away, clean up Pointer Capture state.
1397 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001398 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001399 setPointerCaptureLocked(false);
1400 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001401 return;
1402 }
1403 InputTarget target;
1404 target.inputChannel = channel;
1405 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1406 entry->dispatchInProgress = true;
1407 dispatchEventLocked(currentTime, entry, {target});
1408
1409 dropReason = DropReason::NOT_DROPPED;
1410}
1411
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001412void InputDispatcher::dispatchTouchModeChangeLocked(nsecs_t currentTime,
1413 const std::shared_ptr<TouchModeEntry>& entry) {
1414 const std::vector<sp<WindowInfoHandle>>& windowHandles =
1415 getWindowHandlesLocked(mFocusedDisplayId);
1416 if (windowHandles.empty()) {
1417 return;
1418 }
1419 const std::vector<InputTarget> inputTargets =
1420 getInputTargetsFromWindowHandlesLocked(windowHandles);
1421 if (inputTargets.empty()) {
1422 return;
1423 }
1424 entry->dispatchInProgress = true;
1425 dispatchEventLocked(currentTime, entry, inputTargets);
1426}
1427
1428std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1429 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1430 std::vector<InputTarget> inputTargets;
1431 for (const sp<WindowInfoHandle>& handle : windowHandles) {
1432 // TODO(b/193718270): Due to performance concerns, consider notifying visible windows only.
1433 const sp<IBinder>& token = handle->getToken();
1434 if (token == nullptr) {
1435 continue;
1436 }
1437 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1438 if (channel == nullptr) {
1439 continue; // Window has gone away
1440 }
1441 InputTarget target;
1442 target.inputChannel = channel;
1443 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1444 inputTargets.push_back(target);
1445 }
1446 return inputTargets;
1447}
1448
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001449bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001450 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001451 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001452 if (!entry->dispatchInProgress) {
1453 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1454 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1455 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1456 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001457 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001458 // We have seen two identical key downs in a row which indicates that the device
1459 // driver is automatically generating key repeats itself. We take note of the
1460 // repeat here, but we disable our own next key repeat timer since it is clear that
1461 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001462 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1463 // Make sure we don't get key down from a different device. If a different
1464 // device Id has same key pressed down, the new device Id will replace the
1465 // current one to hold the key repeat with repeat count reset.
1466 // In the future when got a KEY_UP on the device id, drop it and do not
1467 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001468 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1469 resetKeyRepeatLocked();
1470 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1471 } else {
1472 // Not a repeat. Save key down state in case we do see a repeat later.
1473 resetKeyRepeatLocked();
1474 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1475 }
1476 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001477 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1478 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001479 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001480 if (DEBUG_INBOUND_EVENT_DETAILS) {
1481 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1482 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001483 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001484 resetKeyRepeatLocked();
1485 }
1486
1487 if (entry->repeatCount == 1) {
1488 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1489 } else {
1490 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1491 }
1492
1493 entry->dispatchInProgress = true;
1494
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001495 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001496 }
1497
1498 // Handle case where the policy asked us to try again later last time.
1499 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1500 if (currentTime < entry->interceptKeyWakeupTime) {
1501 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1502 *nextWakeupTime = entry->interceptKeyWakeupTime;
1503 }
1504 return false; // wait until next wakeup
1505 }
1506 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1507 entry->interceptKeyWakeupTime = 0;
1508 }
1509
1510 // Give the policy a chance to intercept the key.
1511 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1512 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001513 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001514 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001515
1516 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1517 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1518 };
1519 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001520 return false; // wait for the command to run
1521 } else {
1522 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1523 }
1524 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001525 if (*dropReason == DropReason::NOT_DROPPED) {
1526 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001527 }
1528 }
1529
1530 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001531 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001532 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001533 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1534 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001535 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001536 return true;
1537 }
1538
1539 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001540 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001541 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001542 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001543 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001544 return false;
1545 }
1546
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001547 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001548 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001549 return true;
1550 }
1551
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001552 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001553 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001554
1555 // Dispatch the key.
1556 dispatchEventLocked(currentTime, entry, inputTargets);
1557 return true;
1558}
1559
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001560void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001561 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1562 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1563 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1564 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1565 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1566 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1567 entry.metaState, entry.repeatCount, entry.downTime);
1568 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001569}
1570
Prabir Pradhancef936d2021-07-21 16:17:52 +00001571void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1572 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001573 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001574 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1575 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1576 "source=0x%x, sensorType=%s",
1577 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001578 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001579 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001580 auto command = [this, entry]() REQUIRES(mLock) {
1581 scoped_unlock unlock(mLock);
1582
1583 if (entry->accuracyChanged) {
1584 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1585 }
1586 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1587 entry->hwTimestamp, entry->values);
1588 };
1589 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001590}
1591
1592bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001593 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1594 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001595 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001596 }
Chris Yef59a2f42020-10-16 12:55:26 -07001597 { // acquire lock
1598 std::scoped_lock _l(mLock);
1599
1600 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1601 std::shared_ptr<EventEntry> entry = *it;
1602 if (entry->type == EventEntry::Type::SENSOR) {
1603 it = mInboundQueue.erase(it);
1604 releaseInboundEventLocked(entry);
1605 }
1606 }
1607 }
1608 return true;
1609}
1610
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001611bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001612 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001613 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001614 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001615 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001616 entry->dispatchInProgress = true;
1617
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001618 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001619 }
1620
1621 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001622 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001623 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001624 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1625 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001626 return true;
1627 }
1628
1629 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1630
1631 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001632 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001633
1634 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001635 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001636 if (isPointerEvent) {
1637 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001638 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001639 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001640 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001641 } else {
1642 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001643 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001644 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001645 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001646 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001647 return false;
1648 }
1649
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001650 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001651 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001652 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1653 return true;
1654 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001655 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001656 CancelationOptions::Mode mode(isPointerEvent
1657 ? CancelationOptions::CANCEL_POINTER_EVENTS
1658 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1659 CancelationOptions options(mode, "input event injection failed");
1660 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001661 return true;
1662 }
1663
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001664 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001665 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001666
1667 // Dispatch the motion.
1668 if (conflictingPointerActions) {
1669 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001670 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001671 synthesizeCancelationEventsForAllConnectionsLocked(options);
1672 }
1673 dispatchEventLocked(currentTime, entry, inputTargets);
1674 return true;
1675}
1676
chaviw98318de2021-05-19 16:45:23 -05001677void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001678 bool isExiting, const MotionEntry& motionEntry) {
1679 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1680 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1681 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1682 PointerCoords pointerCoords;
1683 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1684 pointerCoords.transform(windowHandle->getInfo()->transform);
1685
1686 std::unique_ptr<DragEntry> dragEntry =
1687 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1688 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1689 pointerCoords.getY());
1690
1691 enqueueInboundEventLocked(std::move(dragEntry));
1692}
1693
1694void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1695 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1696 if (channel == nullptr) {
1697 return; // Window has gone away
1698 }
1699 InputTarget target;
1700 target.inputChannel = channel;
1701 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1702 entry->dispatchInProgress = true;
1703 dispatchEventLocked(currentTime, entry, {target});
1704}
1705
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001706void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001707 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1708 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1709 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001710 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001711 "metaState=0x%x, buttonState=0x%x,"
1712 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1713 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001714 entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
1715 entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.edgeFlags,
1716 entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001717
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001718 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1719 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1720 "x=%f, y=%f, pressure=%f, size=%f, "
1721 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1722 "orientation=%f",
1723 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1724 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1725 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1726 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1727 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1728 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1729 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1730 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1731 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1732 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1733 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001734 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001735}
1736
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001737void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1738 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001739 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001740 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001741 if (DEBUG_DISPATCH_CYCLE) {
1742 ALOGD("dispatchEventToCurrentInputTargets");
1743 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001744
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001745 updateInteractionTokensLocked(*eventEntry, inputTargets);
1746
Michael Wrightd02c5b62014-02-10 15:10:22 -08001747 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1748
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001749 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001750
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001751 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001752 sp<Connection> connection =
1753 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001754 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001755 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001756 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001757 if (DEBUG_FOCUS) {
1758 ALOGD("Dropping event delivery to target with channel '%s' because it "
1759 "is no longer registered with the input dispatcher.",
1760 inputTarget.inputChannel->getName().c_str());
1761 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001762 }
1763 }
1764}
1765
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001766void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1767 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1768 // If the policy decides to close the app, we will get a channel removal event via
1769 // unregisterInputChannel, and will clean up the connection that way. We are already not
1770 // sending new pointers to the connection when it blocked, but focused events will continue to
1771 // pile up.
1772 ALOGW("Canceling events for %s because it is unresponsive",
1773 connection->inputChannel->getName().c_str());
1774 if (connection->status == Connection::STATUS_NORMAL) {
1775 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1776 "application not responding");
1777 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001778 }
1779}
1780
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001781void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001782 if (DEBUG_FOCUS) {
1783 ALOGD("Resetting ANR timeouts.");
1784 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001785
1786 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001787 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001788 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001789}
1790
Tiger Huang721e26f2018-07-24 22:26:19 +08001791/**
1792 * Get the display id that the given event should go to. If this event specifies a valid display id,
1793 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1794 * Focused display is the display that the user most recently interacted with.
1795 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001796int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001797 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001798 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001799 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001800 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1801 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001802 break;
1803 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001804 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001805 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1806 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001807 break;
1808 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001809 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001810 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001811 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001812 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001813 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001814 case EventEntry::Type::SENSOR:
1815 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001816 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001817 return ADISPLAY_ID_NONE;
1818 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001819 }
1820 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1821}
1822
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001823bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1824 const char* focusedWindowName) {
1825 if (mAnrTracker.empty()) {
1826 // already processed all events that we waited for
1827 mKeyIsWaitingForEventsTimeout = std::nullopt;
1828 return false;
1829 }
1830
1831 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1832 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001833 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001834 mKeyIsWaitingForEventsTimeout = currentTime +
1835 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1836 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001837 return true;
1838 }
1839
1840 // We still have pending events, and already started the timer
1841 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1842 return true; // Still waiting
1843 }
1844
1845 // Waited too long, and some connection still hasn't processed all motions
1846 // Just send the key to the focused window
1847 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1848 focusedWindowName);
1849 mKeyIsWaitingForEventsTimeout = std::nullopt;
1850 return false;
1851}
1852
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001853InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1854 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1855 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001856 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001857
Tiger Huang721e26f2018-07-24 22:26:19 +08001858 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001859 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001860 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001861 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1862
Michael Wrightd02c5b62014-02-10 15:10:22 -08001863 // If there is no currently focused window and no focused application
1864 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001865 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1866 ALOGI("Dropping %s event because there is no focused window or focused application in "
1867 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08001868 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001869 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001870 }
1871
Vishnu Nair062a8672021-09-03 16:07:44 -07001872 // Drop key events if requested by input feature
1873 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
1874 return InputEventInjectionResult::FAILED;
1875 }
1876
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001877 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1878 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1879 // start interacting with another application via touch (app switch). This code can be removed
1880 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1881 // an app is expected to have a focused window.
1882 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1883 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1884 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001885 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1886 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1887 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001888 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001889 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001890 ALOGW("Waiting because no window has focus but %s may eventually add a "
1891 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001892 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001893 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001894 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001895 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1896 // Already raised ANR. Drop the event
1897 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08001898 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001899 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001900 } else {
1901 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001902 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001903 }
1904 }
1905
1906 // we have a valid, non-null focused window
1907 resetNoFocusedWindowTimeoutLocked();
1908
Michael Wrightd02c5b62014-02-10 15:10:22 -08001909 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001910 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001911 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001912 }
1913
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001914 if (focusedWindowHandle->getInfo()->paused) {
1915 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001916 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001917 }
1918
1919 // If the event is a key event, then we must wait for all previous events to
1920 // complete before delivering it because previous events may have the
1921 // side-effect of transferring focus to a different window and we want to
1922 // ensure that the following keys are sent to the new window.
1923 //
1924 // Suppose the user touches a button in a window then immediately presses "A".
1925 // If the button causes a pop-up window to appear then we want to ensure that
1926 // the "A" key is delivered to the new pop-up window. This is because users
1927 // often anticipate pending UI changes when typing on a keyboard.
1928 // To obtain this behavior, we must serialize key events with respect to all
1929 // prior input events.
1930 if (entry.type == EventEntry::Type::KEY) {
1931 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1932 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001933 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001934 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001935 }
1936
1937 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001938 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001939 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1940 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001941
1942 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001943 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001944}
1945
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001946/**
1947 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1948 * that are currently unresponsive.
1949 */
1950std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1951 const std::vector<TouchedMonitor>& monitors) const {
1952 std::vector<TouchedMonitor> responsiveMonitors;
1953 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1954 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1955 sp<Connection> connection = getConnectionLocked(
1956 monitor.monitor.inputChannel->getConnectionToken());
1957 if (connection == nullptr) {
1958 ALOGE("Could not find connection for monitor %s",
1959 monitor.monitor.inputChannel->getName().c_str());
1960 return false;
1961 }
1962 if (!connection->responsive) {
1963 ALOGW("Unresponsive monitor %s will not get the new gesture",
1964 connection->inputChannel->getName().c_str());
1965 return false;
1966 }
1967 return true;
1968 });
1969 return responsiveMonitors;
1970}
1971
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001972InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1973 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1974 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001975 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001976 enum InjectionPermission {
1977 INJECTION_PERMISSION_UNKNOWN,
1978 INJECTION_PERMISSION_GRANTED,
1979 INJECTION_PERMISSION_DENIED
1980 };
1981
Michael Wrightd02c5b62014-02-10 15:10:22 -08001982 // For security reasons, we defer updating the touch state until we are sure that
1983 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001984 int32_t displayId = entry.displayId;
1985 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001986 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1987
1988 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001989 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001990 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05001991 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1992 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001993
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001994 // Copy current touch state into tempTouchState.
1995 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1996 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001997 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001998 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001999 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
2000 mTouchStatesByDisplay.find(displayId);
2001 if (oldStateIt != mTouchStatesByDisplay.end()) {
2002 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002003 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08002004 }
2005
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002006 bool isSplit = tempTouchState.split;
2007 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
2008 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
2009 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002010 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2011 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2012 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
2013 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2014 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002015 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002016 bool wrongDevice = false;
2017 if (newGesture) {
2018 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002019 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002020 ALOGI("Dropping event because a pointer for a different device is already down "
2021 "in display %" PRId32,
2022 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002023 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002024 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002025 switchedDevice = false;
2026 wrongDevice = true;
2027 goto Failed;
2028 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002029 tempTouchState.reset();
2030 tempTouchState.down = down;
2031 tempTouchState.deviceId = entry.deviceId;
2032 tempTouchState.source = entry.source;
2033 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002034 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002035 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002036 ALOGI("Dropping move event because a pointer for a different device is already active "
2037 "in display %" PRId32,
2038 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002039 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002040 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002041 switchedDevice = false;
2042 wrongDevice = true;
2043 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002044 }
2045
2046 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2047 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2048
Garfield Tan00f511d2019-06-12 16:55:40 -07002049 int32_t x;
2050 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002051 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07002052 // Always dispatch mouse events to cursor position.
2053 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002054 x = int32_t(entry.xCursorPosition);
2055 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07002056 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002057 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
2058 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07002059 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002060 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002061 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
2062 isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00002063
2064 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002065 ? findTouchedGestureMonitorsLocked(displayId)
Michael Wright3dd60e22019-03-27 22:06:44 +00002066 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067
Michael Wrightd02c5b62014-02-10 15:10:22 -08002068 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002069 if (newTouchedWindowHandle != nullptr &&
2070 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07002071 // New window supports splitting, but we should never split mouse events.
2072 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002073 } else if (isSplit) {
2074 // New window does not support splitting but we have already split events.
2075 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002076 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002077 }
2078
2079 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002080 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002081 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002082 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002083 }
2084
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002085 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
2086 ALOGI("Not sending touch event to %s because it is paused",
2087 newTouchedWindowHandle->getName().c_str());
2088 newTouchedWindowHandle = nullptr;
2089 }
2090
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002091 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002092 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002093 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
2094 if (!isResponsive) {
2095 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002096 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
2097 newTouchedWindowHandle = nullptr;
2098 }
2099 }
2100
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002101 // Drop events that can't be trusted due to occlusion
2102 if (newTouchedWindowHandle != nullptr &&
2103 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2104 TouchOcclusionInfo occlusionInfo =
2105 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002106 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002107 if (DEBUG_TOUCH_OCCLUSION) {
2108 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2109 for (const auto& log : occlusionInfo.debugInfo) {
2110 ALOGD("%s", log.c_str());
2111 }
2112 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00002113 sendUntrustedTouchCommandLocked(occlusionInfo.obscuringPackage);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002114 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2115 ALOGW("Dropping untrusted touch event due to %s/%d",
2116 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2117 newTouchedWindowHandle = nullptr;
2118 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002119 }
2120 }
2121
Vishnu Nair062a8672021-09-03 16:07:44 -07002122 // Drop touch events if requested by input feature
2123 if (newTouchedWindowHandle != nullptr && shouldDropInput(entry, newTouchedWindowHandle)) {
2124 newTouchedWindowHandle = nullptr;
2125 }
2126
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002127 // Also don't send the new touch event to unresponsive gesture monitors
2128 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
2129
Michael Wright3dd60e22019-03-27 22:06:44 +00002130 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
2131 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002132 "(%d, %d) in display %" PRId32 ".",
2133 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002134 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00002135 goto Failed;
2136 }
2137
2138 if (newTouchedWindowHandle != nullptr) {
2139 // Set target flags.
2140 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
2141 if (isSplit) {
2142 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002143 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002144 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2145 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2146 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2147 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2148 }
2149
2150 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07002151 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2152 newHoverWindowHandle = nullptr;
2153 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002154 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002155 }
2156
2157 // Update the temporary touch state.
2158 BitSet32 pointerIds;
2159 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002160 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002161 pointerIds.markBit(pointerId);
2162 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002163 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002164 }
2165
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002166 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002167 } else {
2168 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2169
2170 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002171 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002172 if (DEBUG_FOCUS) {
2173 ALOGD("Dropping event because the pointer is not down or we previously "
2174 "dropped the pointer down event in display %" PRId32,
2175 displayId);
2176 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002177 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002178 goto Failed;
2179 }
2180
arthurhung6d4bed92021-03-17 11:59:33 +08002181 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002182
Michael Wrightd02c5b62014-02-10 15:10:22 -08002183 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002184 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002185 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002186 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2187 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002188
chaviw98318de2021-05-19 16:45:23 -05002189 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002190 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002191 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Vishnu Nair062a8672021-09-03 16:07:44 -07002192
2193 // Drop touch events if requested by input feature
2194 if (newTouchedWindowHandle != nullptr &&
2195 shouldDropInput(entry, newTouchedWindowHandle)) {
2196 newTouchedWindowHandle = nullptr;
2197 }
2198
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002199 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2200 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002201 if (DEBUG_FOCUS) {
2202 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2203 oldTouchedWindowHandle->getName().c_str(),
2204 newTouchedWindowHandle->getName().c_str(), displayId);
2205 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002206 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002207 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2208 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2209 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002210
2211 // Make a slippery entrance into the new window.
2212 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2213 isSplit = true;
2214 }
2215
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002216 int32_t targetFlags =
2217 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002218 if (isSplit) {
2219 targetFlags |= InputTarget::FLAG_SPLIT;
2220 }
2221 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2222 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002223 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2224 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002225 }
2226
2227 BitSet32 pointerIds;
2228 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002229 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002230 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002231 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002232 }
2233 }
2234 }
2235
2236 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002237 // Let the previous window know that the hover sequence is over, unless we already did it
2238 // when dispatching it as is to newTouchedWindowHandle.
2239 if (mLastHoverWindowHandle != nullptr &&
2240 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2241 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002242 if (DEBUG_HOVER) {
2243 ALOGD("Sending hover exit event to window %s.",
2244 mLastHoverWindowHandle->getName().c_str());
2245 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002246 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2247 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002248 }
2249
Garfield Tandf26e862020-07-01 20:18:19 -07002250 // Let the new window know that the hover sequence is starting, unless we already did it
2251 // when dispatching it as is to newTouchedWindowHandle.
2252 if (newHoverWindowHandle != nullptr &&
2253 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2254 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002255 if (DEBUG_HOVER) {
2256 ALOGD("Sending hover enter event to window %s.",
2257 newHoverWindowHandle->getName().c_str());
2258 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002259 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2260 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2261 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002262 }
2263 }
2264
2265 // Check permission to inject into all touched foreground windows and ensure there
2266 // is at least one touched foreground window.
2267 {
2268 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002269 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002270 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2271 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002272 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002273 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002274 injectionPermission = INJECTION_PERMISSION_DENIED;
2275 goto Failed;
2276 }
2277 }
2278 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002279 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002280 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002281 ALOGI("Dropping event because there is no touched foreground window in display "
2282 "%" PRId32 " or gesture monitor to receive it.",
2283 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002284 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002285 goto Failed;
2286 }
2287
2288 // Permission granted to injection into all touched foreground windows.
2289 injectionPermission = INJECTION_PERMISSION_GRANTED;
2290 }
2291
2292 // Check whether windows listening for outside touches are owned by the same UID. If it is
2293 // set the policy flag that we will not reveal coordinate information to this window.
2294 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002295 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002296 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002297 if (foregroundWindowHandle) {
2298 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002299 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002300 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002301 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2302 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2303 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002304 InputTarget::FLAG_ZERO_COORDS,
2305 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002306 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002307 }
2308 }
2309 }
2310 }
2311
Michael Wrightd02c5b62014-02-10 15:10:22 -08002312 // If this is the first pointer going down and the touched window has a wallpaper
2313 // then also add the touched wallpaper windows so they are locked in for the duration
2314 // of the touch gesture.
2315 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2316 // engine only supports touch events. We would need to add a mechanism similar
2317 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2318 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002319 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002320 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002321 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
chaviw98318de2021-05-19 16:45:23 -05002322 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002323 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002324 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2325 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002326 if (info->displayId == displayId &&
chaviw98318de2021-05-19 16:45:23 -05002327 windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002328 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002329 .addOrUpdateWindow(windowHandle,
2330 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2331 InputTarget::
2332 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2333 InputTarget::FLAG_DISPATCH_AS_IS,
2334 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002335 }
2336 }
2337 }
2338 }
2339
2340 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002341 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002342
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002343 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002344 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002345 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002346 }
2347
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002348 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002349 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002350 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002351 }
2352
Michael Wrightd02c5b62014-02-10 15:10:22 -08002353 // Drop the outside or hover touch windows since we will not care about them
2354 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002355 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002356
2357Failed:
2358 // Check injection permission once and for all.
2359 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002360 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002361 injectionPermission = INJECTION_PERMISSION_GRANTED;
2362 } else {
2363 injectionPermission = INJECTION_PERMISSION_DENIED;
2364 }
2365 }
2366
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002367 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2368 return injectionResult;
2369 }
2370
Michael Wrightd02c5b62014-02-10 15:10:22 -08002371 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002372 if (!wrongDevice) {
2373 if (switchedDevice) {
2374 if (DEBUG_FOCUS) {
2375 ALOGD("Conflicting pointer actions: Switched to a different device.");
2376 }
2377 *outConflictingPointerActions = true;
2378 }
2379
2380 if (isHoverAction) {
2381 // Started hovering, therefore no longer down.
2382 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002383 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002384 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2385 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002386 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002387 *outConflictingPointerActions = true;
2388 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002389 tempTouchState.reset();
2390 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2391 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2392 tempTouchState.deviceId = entry.deviceId;
2393 tempTouchState.source = entry.source;
2394 tempTouchState.displayId = displayId;
2395 }
2396 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2397 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2398 // All pointers up or canceled.
2399 tempTouchState.reset();
2400 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2401 // First pointer went down.
2402 if (oldState && oldState->down) {
2403 if (DEBUG_FOCUS) {
2404 ALOGD("Conflicting pointer actions: Down received while already down.");
2405 }
2406 *outConflictingPointerActions = true;
2407 }
2408 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2409 // One pointer went up.
2410 if (isSplit) {
2411 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2412 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002413
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002414 for (size_t i = 0; i < tempTouchState.windows.size();) {
2415 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2416 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2417 touchedWindow.pointerIds.clearBit(pointerId);
2418 if (touchedWindow.pointerIds.isEmpty()) {
2419 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2420 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002421 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002422 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002423 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002424 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002425 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002426 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002427
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002428 // Save changes unless the action was scroll in which case the temporary touch
2429 // state was only valid for this one action.
2430 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2431 if (tempTouchState.displayId >= 0) {
2432 mTouchStatesByDisplay[displayId] = tempTouchState;
2433 } else {
2434 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002435 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002436 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002437
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002438 // Update hover state.
2439 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002440 }
2441
Michael Wrightd02c5b62014-02-10 15:10:22 -08002442 return injectionResult;
2443}
2444
arthurhung6d4bed92021-03-17 11:59:33 +08002445void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
chaviw98318de2021-05-19 16:45:23 -05002446 const sp<WindowInfoHandle> dropWindow =
arthurhung6d4bed92021-03-17 11:59:33 +08002447 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002448 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002449 if (dropWindow) {
2450 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002451 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002452 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002453 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002454 }
2455 mDragState.reset();
2456}
2457
2458void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2459 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002460 return;
2461 }
2462
arthurhung6d4bed92021-03-17 11:59:33 +08002463 if (!mDragState->isStartDrag) {
2464 mDragState->isStartDrag = true;
2465 mDragState->isStylusButtonDownAtStart =
2466 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2467 }
2468
arthurhungb89ccb02020-12-30 16:19:01 +08002469 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2470 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2471 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2472 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002473 // Handle the special case : stylus button no longer pressed.
2474 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2475 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2476 finishDragAndDrop(entry.displayId, x, y);
2477 return;
2478 }
2479
chaviw98318de2021-05-19 16:45:23 -05002480 const sp<WindowInfoHandle> hoverWindowHandle =
arthurhung6d4bed92021-03-17 11:59:33 +08002481 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002482 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002483 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002484 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2485 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2486 if (mDragState->dragHoverWindowHandle != nullptr) {
2487 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2488 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002489 }
arthurhung6d4bed92021-03-17 11:59:33 +08002490 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002491 }
2492 // enqueue drag location if needed.
2493 if (hoverWindowHandle != nullptr) {
2494 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2495 }
arthurhung6d4bed92021-03-17 11:59:33 +08002496 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2497 finishDragAndDrop(entry.displayId, x, y);
2498 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002499 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002500 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002501 }
2502}
2503
chaviw98318de2021-05-19 16:45:23 -05002504void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002505 int32_t targetFlags, BitSet32 pointerIds,
2506 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002507 std::vector<InputTarget>::iterator it =
2508 std::find_if(inputTargets.begin(), inputTargets.end(),
2509 [&windowHandle](const InputTarget& inputTarget) {
2510 return inputTarget.inputChannel->getConnectionToken() ==
2511 windowHandle->getToken();
2512 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002513
chaviw98318de2021-05-19 16:45:23 -05002514 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002515
2516 if (it == inputTargets.end()) {
2517 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002518 std::shared_ptr<InputChannel> inputChannel =
2519 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002520 if (inputChannel == nullptr) {
2521 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2522 return;
2523 }
2524 inputTarget.inputChannel = inputChannel;
2525 inputTarget.flags = targetFlags;
2526 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002527 const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
2528 if (displayInfoIt != mDisplayInfos.end()) {
2529 const auto& displayInfo = displayInfoIt->second;
2530 inputTarget.displayOrientation = displayInfo.transform.getOrientation();
2531 inputTarget.displaySize = int2(displayInfo.logicalWidth, displayInfo.logicalHeight);
2532 } else {
2533 ALOGI_IF(isPerWindowInputRotationEnabled(),
2534 "DisplayInfo not found for window on display: %d", windowInfo->displayId);
2535 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002536 inputTargets.push_back(inputTarget);
2537 it = inputTargets.end() - 1;
2538 }
2539
2540 ALOG_ASSERT(it->flags == targetFlags);
2541 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2542
chaviw1ff3d1e2020-07-01 15:53:47 -07002543 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002544}
2545
Michael Wright3dd60e22019-03-27 22:06:44 +00002546void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002547 int32_t displayId, float xOffset,
2548 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002549 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2550 mGlobalMonitorsByDisplay.find(displayId);
2551
2552 if (it != mGlobalMonitorsByDisplay.end()) {
2553 const std::vector<Monitor>& monitors = it->second;
2554 for (const Monitor& monitor : monitors) {
2555 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002556 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002557 }
2558}
2559
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002560void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2561 float yOffset,
2562 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002563 InputTarget target;
2564 target.inputChannel = monitor.inputChannel;
2565 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002566 ui::Transform t;
2567 t.set(xOffset, yOffset);
2568 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002569 inputTargets.push_back(target);
2570}
2571
chaviw98318de2021-05-19 16:45:23 -05002572bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002573 const InjectionState* injectionState) {
2574 if (injectionState &&
2575 (windowHandle == nullptr ||
2576 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2577 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002578 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002579 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002580 "owned by uid %d",
2581 injectionState->injectorPid, injectionState->injectorUid,
2582 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002583 } else {
2584 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002585 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002586 }
2587 return false;
2588 }
2589 return true;
2590}
2591
Robert Carrc9bf1d32020-04-13 17:21:08 -07002592/**
2593 * Indicate whether one window handle should be considered as obscuring
2594 * another window handle. We only check a few preconditions. Actually
2595 * checking the bounds is left to the caller.
2596 */
chaviw98318de2021-05-19 16:45:23 -05002597static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2598 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002599 // Compare by token so cloned layers aren't counted
2600 if (haveSameToken(windowHandle, otherHandle)) {
2601 return false;
2602 }
2603 auto info = windowHandle->getInfo();
2604 auto otherInfo = otherHandle->getInfo();
2605 if (!otherInfo->visible) {
2606 return false;
chaviw98318de2021-05-19 16:45:23 -05002607 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002608 // Those act as if they were invisible, so we don't need to flag them.
2609 // We do want to potentially flag touchable windows even if they have 0
2610 // opacity, since they can consume touches and alter the effects of the
2611 // user interaction (eg. apps that rely on
2612 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2613 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2614 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002615 } else if (info->ownerUid == otherInfo->ownerUid) {
2616 // If ownerUid is the same we don't generate occlusion events as there
2617 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002618 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002619 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002620 return false;
2621 } else if (otherInfo->displayId != info->displayId) {
2622 return false;
2623 }
2624 return true;
2625}
2626
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002627/**
2628 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2629 * untrusted, one should check:
2630 *
2631 * 1. If result.hasBlockingOcclusion is true.
2632 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2633 * BLOCK_UNTRUSTED.
2634 *
2635 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2636 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2637 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2638 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2639 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2640 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2641 *
2642 * If neither of those is true, then it means the touch can be allowed.
2643 */
2644InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002645 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2646 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002647 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002648 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002649 TouchOcclusionInfo info;
2650 info.hasBlockingOcclusion = false;
2651 info.obscuringOpacity = 0;
2652 info.obscuringUid = -1;
2653 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002654 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002655 if (windowHandle == otherHandle) {
2656 break; // All future windows are below us. Exit early.
2657 }
chaviw98318de2021-05-19 16:45:23 -05002658 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002659 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2660 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002661 if (DEBUG_TOUCH_OCCLUSION) {
2662 info.debugInfo.push_back(
2663 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2664 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002665 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2666 // we perform the checks below to see if the touch can be propagated or not based on the
2667 // window's touch occlusion mode
2668 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2669 info.hasBlockingOcclusion = true;
2670 info.obscuringUid = otherInfo->ownerUid;
2671 info.obscuringPackage = otherInfo->packageName;
2672 break;
2673 }
2674 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2675 uint32_t uid = otherInfo->ownerUid;
2676 float opacity =
2677 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2678 // Given windows A and B:
2679 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2680 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2681 opacityByUid[uid] = opacity;
2682 if (opacity > info.obscuringOpacity) {
2683 info.obscuringOpacity = opacity;
2684 info.obscuringUid = uid;
2685 info.obscuringPackage = otherInfo->packageName;
2686 }
2687 }
2688 }
2689 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002690 if (DEBUG_TOUCH_OCCLUSION) {
2691 info.debugInfo.push_back(
2692 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2693 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002694 return info;
2695}
2696
chaviw98318de2021-05-19 16:45:23 -05002697std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002698 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002699 return StringPrintf(INDENT2
2700 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2701 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2702 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2703 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Dominik Laskowski75788452021-02-09 18:51:25 -08002704 isTouchedWindow ? "[TOUCHED] " : "", ftl::enum_string(info->type).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002705 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002706 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2707 info->frameTop, info->frameRight, info->frameBottom,
2708 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002709 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2710 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2711 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002712}
2713
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002714bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2715 if (occlusionInfo.hasBlockingOcclusion) {
2716 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2717 occlusionInfo.obscuringUid);
2718 return false;
2719 }
2720 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2721 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2722 "%.2f, maximum allowed = %.2f)",
2723 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2724 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2725 return false;
2726 }
2727 return true;
2728}
2729
chaviw98318de2021-05-19 16:45:23 -05002730bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002731 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002732 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002733 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2734 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002735 if (windowHandle == otherHandle) {
2736 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002737 }
chaviw98318de2021-05-19 16:45:23 -05002738 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002739 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002740 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002741 return true;
2742 }
2743 }
2744 return false;
2745}
2746
chaviw98318de2021-05-19 16:45:23 -05002747bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002748 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002749 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2750 const WindowInfo* windowInfo = windowHandle->getInfo();
2751 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002752 if (windowHandle == otherHandle) {
2753 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002754 }
chaviw98318de2021-05-19 16:45:23 -05002755 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002756 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002757 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002758 return true;
2759 }
2760 }
2761 return false;
2762}
2763
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002764std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002765 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002766 if (applicationHandle != nullptr) {
2767 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002768 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002769 } else {
2770 return applicationHandle->getName();
2771 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002772 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002773 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002774 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002775 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002776 }
2777}
2778
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002779void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002780 if (eventEntry.type == EventEntry::Type::FOCUS ||
arthurhungb89ccb02020-12-30 16:19:01 +08002781 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED ||
2782 eventEntry.type == EventEntry::Type::DRAG) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002783 // Focus or pointer capture changed events are passed to apps, but do not represent user
2784 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002785 return;
2786 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002787 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002788 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002789 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002790 const WindowInfo* info = focusedWindowHandle->getInfo();
2791 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002792 if (DEBUG_DISPATCH_CYCLE) {
2793 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2794 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002795 return;
2796 }
2797 }
2798
2799 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002800 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002801 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002802 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2803 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002804 return;
2805 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002806
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002807 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002808 eventType = USER_ACTIVITY_EVENT_TOUCH;
2809 }
2810 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002811 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002812 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002813 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2814 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002815 return;
2816 }
2817 eventType = USER_ACTIVITY_EVENT_BUTTON;
2818 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002819 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07002820 case EventEntry::Type::TOUCH_MODE_CHANGED: {
2821 break;
2822 }
2823
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002824 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002825 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002826 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002827 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08002828 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2829 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002830 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08002831 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002832 break;
2833 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002834 }
2835
Prabir Pradhancef936d2021-07-21 16:17:52 +00002836 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2837 REQUIRES(mLock) {
2838 scoped_unlock unlock(mLock);
2839 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2840 };
2841 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002842}
2843
2844void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002845 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002846 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002847 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002848 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002849 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002850 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002851 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002852 ATRACE_NAME(message.c_str());
2853 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002854 if (DEBUG_DISPATCH_CYCLE) {
2855 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2856 "globalScaleFactor=%f, pointerIds=0x%x %s",
2857 connection->getInputChannelName().c_str(), inputTarget.flags,
2858 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2859 inputTarget.getPointerInfoString().c_str());
2860 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002861
2862 // Skip this event if the connection status is not normal.
2863 // We don't want to enqueue additional outbound events if the connection is broken.
2864 if (connection->status != Connection::STATUS_NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002865 if (DEBUG_DISPATCH_CYCLE) {
2866 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
2867 connection->getInputChannelName().c_str(), connection->getStatusLabel());
2868 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002869 return;
2870 }
2871
2872 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002873 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2874 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2875 "Entry type %s should not have FLAG_SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08002876 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002877
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002878 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002879 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002880 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002881 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002882 if (!splitMotionEntry) {
2883 return; // split event was dropped
2884 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002885 if (DEBUG_FOCUS) {
2886 ALOGD("channel '%s' ~ Split motion event.",
2887 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002888 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002889 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002890 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2891 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002892 return;
2893 }
2894 }
2895
2896 // Not splitting. Enqueue dispatch entries for the event as is.
2897 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2898}
2899
2900void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002901 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002902 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002903 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002904 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002905 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002906 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002907 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002908 ATRACE_NAME(message.c_str());
2909 }
2910
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002911 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002912
2913 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002914 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002915 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002916 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002917 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002918 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002919 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002920 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002921 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002922 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002923 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002924 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002925 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002926
2927 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002928 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002929 startDispatchCycleLocked(currentTime, connection);
2930 }
2931}
2932
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002933void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002934 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002935 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002936 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002937 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002938 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2939 connection->getInputChannelName().c_str(),
2940 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002941 ATRACE_NAME(message.c_str());
2942 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002943 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002944 if (!(inputTargetFlags & dispatchMode)) {
2945 return;
2946 }
2947 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2948
2949 // This is a new event.
2950 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002951 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002952 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002953
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002954 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2955 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002956 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002957 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002958 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002959 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002960 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002961 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002962 dispatchEntry->resolvedAction = keyEntry.action;
2963 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002964
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002965 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2966 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002967 if (DEBUG_DISPATCH_CYCLE) {
2968 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
2969 "event",
2970 connection->getInputChannelName().c_str());
2971 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002972 return; // skip the inconsistent event
2973 }
2974 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002975 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002976
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002977 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002978 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002979 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2980 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2981 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2982 static_cast<int32_t>(IdGenerator::Source::OTHER);
2983 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002984 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2985 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2986 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2987 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2988 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2989 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2990 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2991 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2992 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2993 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2994 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002995 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002996 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002997 }
2998 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002999 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3000 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003001 if (DEBUG_DISPATCH_CYCLE) {
3002 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
3003 "enter event",
3004 connection->getInputChannelName().c_str());
3005 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003006 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
3007 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003008 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3009 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003010
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003011 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003012 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
3013 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3014 }
3015 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
3016 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3017 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003018
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003019 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
3020 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003021 if (DEBUG_DISPATCH_CYCLE) {
3022 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
3023 "event",
3024 connection->getInputChannelName().c_str());
3025 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003026 return; // skip the inconsistent event
3027 }
3028
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003029 dispatchEntry->resolvedEventId =
3030 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
3031 ? mIdGenerator.nextId()
3032 : motionEntry.id;
3033 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
3034 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3035 ") to MotionEvent(id=0x%" PRIx32 ").",
3036 motionEntry.id, dispatchEntry->resolvedEventId);
3037 ATRACE_NAME(message.c_str());
3038 }
3039
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003040 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3041 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
3042 // Skip reporting pointer down outside focus to the policy.
3043 break;
3044 }
3045
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003046 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003047 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003048
3049 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003050 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003051 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003052 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003053 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3054 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003055 break;
3056 }
Chris Yef59a2f42020-10-16 12:55:26 -07003057 case EventEntry::Type::SENSOR: {
3058 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3059 break;
3060 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003061 case EventEntry::Type::CONFIGURATION_CHANGED:
3062 case EventEntry::Type::DEVICE_RESET: {
3063 LOG_ALWAYS_FATAL("%s events should not go to apps",
Dominik Laskowski75788452021-02-09 18:51:25 -08003064 ftl::enum_string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003065 break;
3066 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003067 }
3068
3069 // Remember that we are waiting for this dispatch to complete.
3070 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003071 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003072 }
3073
3074 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003075 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003076 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003077}
3078
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003079/**
3080 * This function is purely for debugging. It helps us understand where the user interaction
3081 * was taking place. For example, if user is touching launcher, we will see a log that user
3082 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3083 * We will see both launcher and wallpaper in that list.
3084 * Once the interaction with a particular set of connections starts, no new logs will be printed
3085 * until the set of interacted connections changes.
3086 *
3087 * The following items are skipped, to reduce the logspam:
3088 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3089 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3090 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3091 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3092 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003093 */
3094void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3095 const std::vector<InputTarget>& targets) {
3096 // Skip ACTION_UP events, and all events other than keys and motions
3097 if (entry.type == EventEntry::Type::KEY) {
3098 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3099 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3100 return;
3101 }
3102 } else if (entry.type == EventEntry::Type::MOTION) {
3103 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3104 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3105 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3106 return;
3107 }
3108 } else {
3109 return; // Not a key or a motion
3110 }
3111
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003112 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003113 std::vector<sp<Connection>> newConnections;
3114 for (const InputTarget& target : targets) {
3115 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3116 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3117 continue; // Skip windows that receive ACTION_OUTSIDE
3118 }
3119
3120 sp<IBinder> token = target.inputChannel->getConnectionToken();
3121 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003122 if (connection == nullptr) {
3123 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003124 }
3125 newConnectionTokens.insert(std::move(token));
3126 newConnections.emplace_back(connection);
3127 }
3128 if (newConnectionTokens == mInteractionConnectionTokens) {
3129 return; // no change
3130 }
3131 mInteractionConnectionTokens = newConnectionTokens;
3132
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003133 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003134 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003135 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003136 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003137 std::string message = "Interaction with: " + targetList;
3138 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003139 message += "<none>";
3140 }
3141 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3142}
3143
chaviwfd6d3512019-03-25 13:23:49 -07003144void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003145 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003146 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003147 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3148 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003149 return;
3150 }
3151
Vishnu Nairc519ff72021-01-21 08:23:08 -08003152 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003153 if (focusedToken == token) {
3154 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003155 return;
3156 }
3157
Prabir Pradhancef936d2021-07-21 16:17:52 +00003158 auto command = [this, token]() REQUIRES(mLock) {
3159 scoped_unlock unlock(mLock);
3160 mPolicy->onPointerDownOutsideFocus(token);
3161 };
3162 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003163}
3164
3165void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003166 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003167 if (ATRACE_ENABLED()) {
3168 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003169 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003170 ATRACE_NAME(message.c_str());
3171 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003172 if (DEBUG_DISPATCH_CYCLE) {
3173 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3174 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003175
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003176 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3177 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003178 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003179 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003180 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003181 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003182
3183 // Publish the event.
3184 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003185 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3186 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003187 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003188 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3189 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003190
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003191 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003192 status = connection->inputPublisher
3193 .publishKeyEvent(dispatchEntry->seq,
3194 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3195 keyEntry.source, keyEntry.displayId,
3196 std::move(hmac), dispatchEntry->resolvedAction,
3197 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3198 keyEntry.scanCode, keyEntry.metaState,
3199 keyEntry.repeatCount, keyEntry.downTime,
3200 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003201 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003202 }
3203
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003204 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003205 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003206
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003207 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003208 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003209
chaviw82357092020-01-28 13:13:06 -08003210 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003211 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003212 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3213 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003214 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003215 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3216 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003217 // Don't apply window scale here since we don't want scale to affect raw
3218 // coordinates. The scale will be sent back to the client and applied
3219 // later when requesting relative coordinates.
3220 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3221 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003222 }
3223 usingCoords = scaledCoords;
3224 }
3225 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003226 // We don't want the dispatch target to know.
3227 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003228 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003229 scaledCoords[i].clear();
3230 }
3231 usingCoords = scaledCoords;
3232 }
3233 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003234
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003235 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003236
3237 // Publish the motion event.
3238 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003239 .publishMotionEvent(dispatchEntry->seq,
3240 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003241 motionEntry.deviceId, motionEntry.source,
3242 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003243 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003244 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003245 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003246 motionEntry.edgeFlags, motionEntry.metaState,
3247 motionEntry.buttonState,
3248 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003249 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003250 motionEntry.xPrecision, motionEntry.yPrecision,
3251 motionEntry.xCursorPosition,
3252 motionEntry.yCursorPosition,
Evan Rosky09576692021-07-01 12:22:09 -07003253 dispatchEntry->displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -07003254 dispatchEntry->displaySize.x,
3255 dispatchEntry->displaySize.y,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003256 motionEntry.downTime, motionEntry.eventTime,
3257 motionEntry.pointerCount,
3258 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003259 break;
3260 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003261
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003262 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003263 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003264 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003265 focusEntry.id,
3266 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003267 mInTouchMode);
3268 break;
3269 }
3270
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003271 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3272 const TouchModeEntry& touchModeEntry =
3273 static_cast<const TouchModeEntry&>(eventEntry);
3274 status = connection->inputPublisher
3275 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3276 touchModeEntry.inTouchMode);
3277
3278 break;
3279 }
3280
Prabir Pradhan99987712020-11-10 18:43:05 -08003281 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3282 const auto& captureEntry =
3283 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3284 status = connection->inputPublisher
3285 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003286 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003287 break;
3288 }
3289
arthurhungb89ccb02020-12-30 16:19:01 +08003290 case EventEntry::Type::DRAG: {
3291 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3292 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3293 dragEntry.id, dragEntry.x,
3294 dragEntry.y,
3295 dragEntry.isExiting);
3296 break;
3297 }
3298
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003299 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003300 case EventEntry::Type::DEVICE_RESET:
3301 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003302 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003303 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003304 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003305 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003306 }
3307
3308 // Check the result.
3309 if (status) {
3310 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003311 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003312 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003313 "This is unexpected because the wait queue is empty, so the pipe "
3314 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003315 "event to it, status=%s(%d)",
3316 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3317 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3319 } else {
3320 // Pipe is full and we are waiting for the app to finish process some events
3321 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003322 if (DEBUG_DISPATCH_CYCLE) {
3323 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3324 "waiting for the application to catch up",
3325 connection->getInputChannelName().c_str());
3326 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327 }
3328 } else {
3329 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003330 "status=%s(%d)",
3331 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3332 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003333 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3334 }
3335 return;
3336 }
3337
3338 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003339 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3340 connection->outboundQueue.end(),
3341 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003342 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003343 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003344 if (connection->responsive) {
3345 mAnrTracker.insert(dispatchEntry->timeoutTime,
3346 connection->inputChannel->getConnectionToken());
3347 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003348 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003349 }
3350}
3351
chaviw09c8d2d2020-08-24 15:48:26 -07003352std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3353 size_t size;
3354 switch (event.type) {
3355 case VerifiedInputEvent::Type::KEY: {
3356 size = sizeof(VerifiedKeyEvent);
3357 break;
3358 }
3359 case VerifiedInputEvent::Type::MOTION: {
3360 size = sizeof(VerifiedMotionEvent);
3361 break;
3362 }
3363 }
3364 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3365 return mHmacKeyManager.sign(start, size);
3366}
3367
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003368const std::array<uint8_t, 32> InputDispatcher::getSignature(
3369 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3370 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3371 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3372 // Only sign events up and down events as the purely move events
3373 // are tied to their up/down counterparts so signing would be redundant.
3374 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3375 verifiedEvent.actionMasked = actionMasked;
3376 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003377 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003378 }
3379 return INVALID_HMAC;
3380}
3381
3382const std::array<uint8_t, 32> InputDispatcher::getSignature(
3383 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3384 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3385 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3386 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003387 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003388}
3389
Michael Wrightd02c5b62014-02-10 15:10:22 -08003390void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003391 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003392 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003393 if (DEBUG_DISPATCH_CYCLE) {
3394 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3395 connection->getInputChannelName().c_str(), seq, toString(handled));
3396 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003397
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003398 if (connection->status == Connection::STATUS_BROKEN ||
3399 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003400 return;
3401 }
3402
3403 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003404 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3405 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3406 };
3407 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003408}
3409
3410void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003411 const sp<Connection>& connection,
3412 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003413 if (DEBUG_DISPATCH_CYCLE) {
3414 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3415 connection->getInputChannelName().c_str(), toString(notify));
3416 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003417
3418 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003419 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003420 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003421 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003422 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003423
3424 // The connection appears to be unrecoverably broken.
3425 // Ignore already broken or zombie connections.
3426 if (connection->status == Connection::STATUS_NORMAL) {
3427 connection->status = Connection::STATUS_BROKEN;
3428
3429 if (notify) {
3430 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003431 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3432 connection->getInputChannelName().c_str());
3433
3434 auto command = [this, connection]() REQUIRES(mLock) {
3435 if (connection->status == Connection::STATUS_ZOMBIE) return;
3436 scoped_unlock unlock(mLock);
3437 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3438 };
3439 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003440 }
3441 }
3442}
3443
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003444void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3445 while (!queue.empty()) {
3446 DispatchEntry* dispatchEntry = queue.front();
3447 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003448 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003449 }
3450}
3451
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003452void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003453 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003454 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003455 }
3456 delete dispatchEntry;
3457}
3458
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003459int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3460 std::scoped_lock _l(mLock);
3461 sp<Connection> connection = getConnectionLocked(connectionToken);
3462 if (connection == nullptr) {
3463 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3464 connectionToken.get(), events);
3465 return 0; // remove the callback
3466 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003467
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003468 bool notify;
3469 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3470 if (!(events & ALOOPER_EVENT_INPUT)) {
3471 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3472 "events=0x%x",
3473 connection->getInputChannelName().c_str(), events);
3474 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003475 }
3476
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003477 nsecs_t currentTime = now();
3478 bool gotOne = false;
3479 status_t status = OK;
3480 for (;;) {
3481 Result<InputPublisher::ConsumerResponse> result =
3482 connection->inputPublisher.receiveConsumerResponse();
3483 if (!result.ok()) {
3484 status = result.error().code();
3485 break;
3486 }
3487
3488 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3489 const InputPublisher::Finished& finish =
3490 std::get<InputPublisher::Finished>(*result);
3491 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3492 finish.consumeTime);
3493 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003494 if (shouldReportMetricsForConnection(*connection)) {
3495 const InputPublisher::Timeline& timeline =
3496 std::get<InputPublisher::Timeline>(*result);
3497 mLatencyTracker
3498 .trackGraphicsLatency(timeline.inputEventId,
3499 connection->inputChannel->getConnectionToken(),
3500 std::move(timeline.graphicsTimeline));
3501 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003502 }
3503 gotOne = true;
3504 }
3505 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003506 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003507 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003508 return 1;
3509 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003510 }
3511
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003512 notify = status != DEAD_OBJECT || !connection->monitor;
3513 if (notify) {
3514 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3515 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3516 status);
3517 }
3518 } else {
3519 // Monitor channels are never explicitly unregistered.
3520 // We do it automatically when the remote endpoint is closed so don't warn about them.
3521 const bool stillHaveWindowHandle =
3522 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3523 notify = !connection->monitor && stillHaveWindowHandle;
3524 if (notify) {
3525 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3526 connection->getInputChannelName().c_str(), events);
3527 }
3528 }
3529
3530 // Remove the channel.
3531 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3532 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003533}
3534
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003535void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003536 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003537 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003538 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003539 }
3540}
3541
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003542void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003543 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003544 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3545 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3546}
3547
3548void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3549 const CancelationOptions& options,
3550 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3551 for (const auto& it : monitorsByDisplay) {
3552 const std::vector<Monitor>& monitors = it.second;
3553 for (const Monitor& monitor : monitors) {
3554 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003555 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003556 }
3557}
3558
Michael Wrightd02c5b62014-02-10 15:10:22 -08003559void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003560 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003561 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003562 if (connection == nullptr) {
3563 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003564 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003565
3566 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003567}
3568
3569void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3570 const sp<Connection>& connection, const CancelationOptions& options) {
3571 if (connection->status == Connection::STATUS_BROKEN) {
3572 return;
3573 }
3574
3575 nsecs_t currentTime = now();
3576
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003577 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003578 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003579
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003580 if (cancelationEvents.empty()) {
3581 return;
3582 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003583 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3584 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3585 "with reality: %s, mode=%d.",
3586 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3587 options.mode);
3588 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003589
3590 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003591 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003592 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3593 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003594 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003595 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003596 target.globalScaleFactor = windowInfo->globalScaleFactor;
3597 }
3598 target.inputChannel = connection->inputChannel;
3599 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3600
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003601 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003602 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003603 switch (cancelationEventEntry->type) {
3604 case EventEntry::Type::KEY: {
3605 logOutboundKeyDetails("cancel - ",
3606 static_cast<const KeyEntry&>(*cancelationEventEntry));
3607 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003608 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003609 case EventEntry::Type::MOTION: {
3610 logOutboundMotionDetails("cancel - ",
3611 static_cast<const MotionEntry&>(*cancelationEventEntry));
3612 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003613 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003614 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003615 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003616 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3617 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003618 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08003619 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003620 break;
3621 }
3622 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003623 case EventEntry::Type::DEVICE_RESET:
3624 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003625 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003626 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003627 break;
3628 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003629 }
3630
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003631 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3632 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003633 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003634
3635 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003636}
3637
Svet Ganov5d3bc372020-01-26 23:11:07 -08003638void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3639 const sp<Connection>& connection) {
3640 if (connection->status == Connection::STATUS_BROKEN) {
3641 return;
3642 }
3643
3644 nsecs_t currentTime = now();
3645
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003646 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003647 connection->inputState.synthesizePointerDownEvents(currentTime);
3648
3649 if (downEvents.empty()) {
3650 return;
3651 }
3652
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003653 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003654 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3655 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003656 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003657
3658 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003659 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003660 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3661 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003662 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003663 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003664 target.globalScaleFactor = windowInfo->globalScaleFactor;
3665 }
3666 target.inputChannel = connection->inputChannel;
3667 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3668
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003669 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003670 switch (downEventEntry->type) {
3671 case EventEntry::Type::MOTION: {
3672 logOutboundMotionDetails("down - ",
3673 static_cast<const MotionEntry&>(*downEventEntry));
3674 break;
3675 }
3676
3677 case EventEntry::Type::KEY:
3678 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003679 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08003680 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003681 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003682 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003683 case EventEntry::Type::SENSOR:
3684 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003685 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003686 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003687 break;
3688 }
3689 }
3690
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003691 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3692 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003693 }
3694
3695 startDispatchCycleLocked(currentTime, connection);
3696}
3697
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003698std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3699 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003700 ALOG_ASSERT(pointerIds.value != 0);
3701
3702 uint32_t splitPointerIndexMap[MAX_POINTERS];
3703 PointerProperties splitPointerProperties[MAX_POINTERS];
3704 PointerCoords splitPointerCoords[MAX_POINTERS];
3705
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003706 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003707 uint32_t splitPointerCount = 0;
3708
3709 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003710 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003711 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003712 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003713 uint32_t pointerId = uint32_t(pointerProperties.id);
3714 if (pointerIds.hasBit(pointerId)) {
3715 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3716 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3717 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003718 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003719 splitPointerCount += 1;
3720 }
3721 }
3722
3723 if (splitPointerCount != pointerIds.count()) {
3724 // This is bad. We are missing some of the pointers that we expected to deliver.
3725 // Most likely this indicates that we received an ACTION_MOVE events that has
3726 // different pointer ids than we expected based on the previous ACTION_DOWN
3727 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3728 // in this way.
3729 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003730 "we expected there to be %d pointers. This probably means we received "
3731 "a broken sequence of pointer ids from the input device.",
3732 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003733 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003734 }
3735
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003736 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003737 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003738 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3739 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003740 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3741 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003742 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003743 uint32_t pointerId = uint32_t(pointerProperties.id);
3744 if (pointerIds.hasBit(pointerId)) {
3745 if (pointerIds.count() == 1) {
3746 // The first/last pointer went down/up.
3747 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003748 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003749 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3750 ? AMOTION_EVENT_ACTION_CANCEL
3751 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003752 } else {
3753 // A secondary pointer went down/up.
3754 uint32_t splitPointerIndex = 0;
3755 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3756 splitPointerIndex += 1;
3757 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003758 action = maskedAction |
3759 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003760 }
3761 } else {
3762 // An unrelated pointer changed.
3763 action = AMOTION_EVENT_ACTION_MOVE;
3764 }
3765 }
3766
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003767 int32_t newId = mIdGenerator.nextId();
3768 if (ATRACE_ENABLED()) {
3769 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3770 ") to MotionEvent(id=0x%" PRIx32 ").",
3771 originalMotionEntry.id, newId);
3772 ATRACE_NAME(message.c_str());
3773 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003774 std::unique_ptr<MotionEntry> splitMotionEntry =
3775 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3776 originalMotionEntry.deviceId, originalMotionEntry.source,
3777 originalMotionEntry.displayId,
3778 originalMotionEntry.policyFlags, action,
3779 originalMotionEntry.actionButton,
3780 originalMotionEntry.flags, originalMotionEntry.metaState,
3781 originalMotionEntry.buttonState,
3782 originalMotionEntry.classification,
3783 originalMotionEntry.edgeFlags,
3784 originalMotionEntry.xPrecision,
3785 originalMotionEntry.yPrecision,
3786 originalMotionEntry.xCursorPosition,
3787 originalMotionEntry.yCursorPosition,
3788 originalMotionEntry.downTime, splitPointerCount,
3789 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003790
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003791 if (originalMotionEntry.injectionState) {
3792 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003793 splitMotionEntry->injectionState->refCount += 1;
3794 }
3795
3796 return splitMotionEntry;
3797}
3798
3799void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003800 if (DEBUG_INBOUND_EVENT_DETAILS) {
3801 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3802 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003803
3804 bool needWake;
3805 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003806 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003807
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003808 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3809 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3810 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003811 } // release lock
3812
3813 if (needWake) {
3814 mLooper->wake();
3815 }
3816}
3817
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003818/**
3819 * If one of the meta shortcuts is detected, process them here:
3820 * Meta + Backspace -> generate BACK
3821 * Meta + Enter -> generate HOME
3822 * This will potentially overwrite keyCode and metaState.
3823 */
3824void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003825 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003826 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3827 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3828 if (keyCode == AKEYCODE_DEL) {
3829 newKeyCode = AKEYCODE_BACK;
3830 } else if (keyCode == AKEYCODE_ENTER) {
3831 newKeyCode = AKEYCODE_HOME;
3832 }
3833 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003834 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003835 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003836 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003837 keyCode = newKeyCode;
3838 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3839 }
3840 } else if (action == AKEY_EVENT_ACTION_UP) {
3841 // In order to maintain a consistent stream of up and down events, check to see if the key
3842 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3843 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003844 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003845 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003846 auto replacementIt = mReplacedKeys.find(replacement);
3847 if (replacementIt != mReplacedKeys.end()) {
3848 keyCode = replacementIt->second;
3849 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003850 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3851 }
3852 }
3853}
3854
Michael Wrightd02c5b62014-02-10 15:10:22 -08003855void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003856 if (DEBUG_INBOUND_EVENT_DETAILS) {
3857 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3858 "policyFlags=0x%x, action=0x%x, "
3859 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3860 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3861 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3862 args->downTime);
3863 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003864 if (!validateKeyEvent(args->action)) {
3865 return;
3866 }
3867
3868 uint32_t policyFlags = args->policyFlags;
3869 int32_t flags = args->flags;
3870 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003871 // InputDispatcher tracks and generates key repeats on behalf of
3872 // whatever notifies it, so repeatCount should always be set to 0
3873 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003874 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3875 policyFlags |= POLICY_FLAG_VIRTUAL;
3876 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3877 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003878 if (policyFlags & POLICY_FLAG_FUNCTION) {
3879 metaState |= AMETA_FUNCTION_ON;
3880 }
3881
3882 policyFlags |= POLICY_FLAG_TRUSTED;
3883
Michael Wright78f24442014-08-06 15:55:28 -07003884 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003885 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003886
Michael Wrightd02c5b62014-02-10 15:10:22 -08003887 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003888 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003889 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3890 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003891
Michael Wright2b3c3302018-03-02 17:19:13 +00003892 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003893 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003894 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3895 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003896 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003897 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003898
Michael Wrightd02c5b62014-02-10 15:10:22 -08003899 bool needWake;
3900 { // acquire lock
3901 mLock.lock();
3902
3903 if (shouldSendKeyToInputFilterLocked(args)) {
3904 mLock.unlock();
3905
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003906 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003907 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3908 return; // event was consumed by the filter
3909 }
3910
3911 mLock.lock();
3912 }
3913
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003914 std::unique_ptr<KeyEntry> newEntry =
3915 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3916 args->displayId, policyFlags, args->action, flags,
3917 keyCode, args->scanCode, metaState, repeatCount,
3918 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003919
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003920 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003921 mLock.unlock();
3922 } // release lock
3923
3924 if (needWake) {
3925 mLooper->wake();
3926 }
3927}
3928
3929bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3930 return mInputFilterEnabled;
3931}
3932
3933void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003934 if (DEBUG_INBOUND_EVENT_DETAILS) {
3935 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3936 "displayId=%" PRId32 ", policyFlags=0x%x, "
3937 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3938 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
3939 "yCursorPosition=%f, downTime=%" PRId64,
3940 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3941 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3942 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3943 args->xCursorPosition, args->yCursorPosition, args->downTime);
3944 for (uint32_t i = 0; i < args->pointerCount; i++) {
3945 ALOGD(" Pointer %d: id=%d, toolType=%d, "
3946 "x=%f, y=%f, pressure=%f, size=%f, "
3947 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3948 "orientation=%f",
3949 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3950 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3951 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3952 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3953 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3954 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3955 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3956 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3957 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3958 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
3959 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003960 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003961 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3962 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003963 return;
3964 }
3965
3966 uint32_t policyFlags = args->policyFlags;
3967 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003968
3969 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003970 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003971 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3972 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003973 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003974 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003975
3976 bool needWake;
3977 { // acquire lock
3978 mLock.lock();
3979
3980 if (shouldSendMotionToInputFilterLocked(args)) {
3981 mLock.unlock();
3982
3983 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003984 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003985 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3986 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003987 args->metaState, args->buttonState, args->classification, transform,
3988 args->xPrecision, args->yPrecision, args->xCursorPosition,
Evan Rosky09576692021-07-01 12:22:09 -07003989 args->yCursorPosition, ui::Transform::ROT_0, INVALID_DISPLAY_SIZE,
3990 INVALID_DISPLAY_SIZE, args->downTime, args->eventTime,
3991 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003992
3993 policyFlags |= POLICY_FLAG_FILTERED;
3994 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3995 return; // event was consumed by the filter
3996 }
3997
3998 mLock.lock();
3999 }
4000
4001 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004002 std::unique_ptr<MotionEntry> newEntry =
4003 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
4004 args->source, args->displayId, policyFlags,
4005 args->action, args->actionButton, args->flags,
4006 args->metaState, args->buttonState,
4007 args->classification, args->edgeFlags,
4008 args->xPrecision, args->yPrecision,
4009 args->xCursorPosition, args->yCursorPosition,
4010 args->downTime, args->pointerCount,
4011 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004012
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004013 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4014 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
4015 !mInputFilterEnabled) {
4016 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
4017 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
4018 }
4019
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004020 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004021 mLock.unlock();
4022 } // release lock
4023
4024 if (needWake) {
4025 mLooper->wake();
4026 }
4027}
4028
Chris Yef59a2f42020-10-16 12:55:26 -07004029void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004030 if (DEBUG_INBOUND_EVENT_DETAILS) {
4031 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4032 " sensorType=%s",
4033 args->id, args->eventTime, args->deviceId, args->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08004034 ftl::enum_string(args->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004035 }
Chris Yef59a2f42020-10-16 12:55:26 -07004036
4037 bool needWake;
4038 { // acquire lock
4039 mLock.lock();
4040
4041 // Just enqueue a new sensor event.
4042 std::unique_ptr<SensorEntry> newEntry =
4043 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
4044 args->source, 0 /* policyFlags*/, args->hwTimestamp,
4045 args->sensorType, args->accuracy,
4046 args->accuracyChanged, args->values);
4047
4048 needWake = enqueueInboundEventLocked(std::move(newEntry));
4049 mLock.unlock();
4050 } // release lock
4051
4052 if (needWake) {
4053 mLooper->wake();
4054 }
4055}
4056
Chris Yefb552902021-02-03 17:18:37 -08004057void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004058 if (DEBUG_INBOUND_EVENT_DETAILS) {
4059 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
4060 args->deviceId, args->isOn);
4061 }
Chris Yefb552902021-02-03 17:18:37 -08004062 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
4063}
4064
Michael Wrightd02c5b62014-02-10 15:10:22 -08004065bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08004066 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004067}
4068
4069void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004070 if (DEBUG_INBOUND_EVENT_DETAILS) {
4071 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4072 "switchMask=0x%08x",
4073 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
4074 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004075
4076 uint32_t policyFlags = args->policyFlags;
4077 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004078 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004079}
4080
4081void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004082 if (DEBUG_INBOUND_EVENT_DETAILS) {
4083 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
4084 args->deviceId);
4085 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004086
4087 bool needWake;
4088 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004089 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004090
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004091 std::unique_ptr<DeviceResetEntry> newEntry =
4092 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
4093 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004094 } // release lock
4095
4096 if (needWake) {
4097 mLooper->wake();
4098 }
4099}
4100
Prabir Pradhan7e186182020-11-10 13:56:45 -08004101void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004102 if (DEBUG_INBOUND_EVENT_DETAILS) {
4103 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004104 args->request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004105 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004106
Prabir Pradhan99987712020-11-10 18:43:05 -08004107 bool needWake;
4108 { // acquire lock
4109 std::scoped_lock _l(mLock);
4110 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004111 args->request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004112 needWake = enqueueInboundEventLocked(std::move(entry));
4113 } // release lock
4114
4115 if (needWake) {
4116 mLooper->wake();
4117 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004118}
4119
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004120InputEventInjectionResult InputDispatcher::injectInputEvent(
4121 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4122 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004123 if (DEBUG_INBOUND_EVENT_DETAILS) {
4124 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
4125 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4126 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
4127 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004128 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004129
4130 policyFlags |= POLICY_FLAG_INJECTED;
4131 if (hasInjectionPermission(injectorPid, injectorUid)) {
4132 policyFlags |= POLICY_FLAG_TRUSTED;
4133 }
4134
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004135 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004136 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4137 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4138 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4139 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4140 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004141 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004142 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004143 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004144 }
4145
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004146 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004147 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004148 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004149 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4150 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004151 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004152 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004153 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004154
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004155 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004156 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4157 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4158 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004159 int32_t keyCode = incomingKey.getKeyCode();
4160 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004161 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004162 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004163 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004164 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004165 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4166 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4167 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004168
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004169 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4170 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004171 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004172
4173 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4174 android::base::Timer t;
4175 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4176 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4177 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4178 std::to_string(t.duration().count()).c_str());
4179 }
4180 }
4181
4182 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004183 std::unique_ptr<KeyEntry> injectedEntry =
4184 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004185 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004186 incomingKey.getDisplayId(), policyFlags, action,
4187 flags, keyCode, incomingKey.getScanCode(), metaState,
4188 incomingKey.getRepeatCount(),
4189 incomingKey.getDownTime());
4190 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004191 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004192 }
4193
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004194 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004195 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
4196 int32_t action = motionEvent.getAction();
4197 size_t pointerCount = motionEvent.getPointerCount();
4198 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
4199 int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004200 int32_t flags = motionEvent.getFlags();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004201 int32_t displayId = motionEvent.getDisplayId();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004202 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004203 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004204 }
4205
4206 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004207 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004208 android::base::Timer t;
4209 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4210 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4211 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4212 std::to_string(t.duration().count()).c_str());
4213 }
4214 }
4215
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004216 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4217 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4218 }
4219
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004220 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004221 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4222 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004223 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004224 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4225 resolvedDeviceId, motionEvent.getSource(),
4226 motionEvent.getDisplayId(), policyFlags, action,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004227 actionButton, flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004228 motionEvent.getButtonState(),
4229 motionEvent.getClassification(),
4230 motionEvent.getEdgeFlags(),
4231 motionEvent.getXPrecision(),
4232 motionEvent.getYPrecision(),
4233 motionEvent.getRawXCursorPosition(),
4234 motionEvent.getRawYCursorPosition(),
4235 motionEvent.getDownTime(), uint32_t(pointerCount),
4236 pointerProperties, samplePointerCoords,
4237 motionEvent.getXOffset(),
4238 motionEvent.getYOffset());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004239 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004240 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004241 sampleEventTimes += 1;
4242 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004243 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004244 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4245 resolvedDeviceId, motionEvent.getSource(),
4246 motionEvent.getDisplayId(), policyFlags,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004247 action, actionButton, flags,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004248 motionEvent.getMetaState(),
4249 motionEvent.getButtonState(),
4250 motionEvent.getClassification(),
4251 motionEvent.getEdgeFlags(),
4252 motionEvent.getXPrecision(),
4253 motionEvent.getYPrecision(),
4254 motionEvent.getRawXCursorPosition(),
4255 motionEvent.getRawYCursorPosition(),
4256 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004257 uint32_t(pointerCount), pointerProperties,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004258 samplePointerCoords, motionEvent.getXOffset(),
4259 motionEvent.getYOffset());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004260 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004261 }
4262 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004263 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004264
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004265 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004266 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004267 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004268 }
4269
4270 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004271 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004272 injectionState->injectionIsAsync = true;
4273 }
4274
4275 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004276 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004277
4278 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004279 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004280 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004281 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004282 }
4283
4284 mLock.unlock();
4285
4286 if (needWake) {
4287 mLooper->wake();
4288 }
4289
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004290 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004291 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004292 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004293
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004294 if (syncMode == InputEventInjectionSync::NONE) {
4295 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004296 } else {
4297 for (;;) {
4298 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004299 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004300 break;
4301 }
4302
4303 nsecs_t remainingTimeout = endTime - now();
4304 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004305 if (DEBUG_INJECTION) {
4306 ALOGD("injectInputEvent - Timed out waiting for injection result "
4307 "to become available.");
4308 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004309 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004310 break;
4311 }
4312
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004313 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004314 }
4315
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004316 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4317 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004318 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004319 if (DEBUG_INJECTION) {
4320 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4321 injectionState->pendingForegroundDispatches);
4322 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004323 nsecs_t remainingTimeout = endTime - now();
4324 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004325 if (DEBUG_INJECTION) {
4326 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4327 "dispatches to finish.");
4328 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004329 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004330 break;
4331 }
4332
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004333 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004334 }
4335 }
4336 }
4337
4338 injectionState->release();
4339 } // release lock
4340
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004341 if (DEBUG_INJECTION) {
4342 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
4343 injectionResult, injectorPid, injectorUid);
4344 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004345
4346 return injectionResult;
4347}
4348
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004349std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004350 std::array<uint8_t, 32> calculatedHmac;
4351 std::unique_ptr<VerifiedInputEvent> result;
4352 switch (event.getType()) {
4353 case AINPUT_EVENT_TYPE_KEY: {
4354 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4355 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4356 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004357 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004358 break;
4359 }
4360 case AINPUT_EVENT_TYPE_MOTION: {
4361 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4362 VerifiedMotionEvent verifiedMotionEvent =
4363 verifiedMotionEventFromMotionEvent(motionEvent);
4364 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004365 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004366 break;
4367 }
4368 default: {
4369 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4370 return nullptr;
4371 }
4372 }
4373 if (calculatedHmac == INVALID_HMAC) {
4374 return nullptr;
4375 }
4376 if (calculatedHmac != event.getHmac()) {
4377 return nullptr;
4378 }
4379 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004380}
4381
Michael Wrightd02c5b62014-02-10 15:10:22 -08004382bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004383 return injectorUid == 0 ||
4384 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004385}
4386
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004387void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004388 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004389 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004390 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004391 if (DEBUG_INJECTION) {
4392 ALOGD("Setting input event injection result to %d. "
4393 "injectorPid=%d, injectorUid=%d",
4394 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
4395 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004396
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004397 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004398 // Log the outcome since the injector did not wait for the injection result.
4399 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004400 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004401 ALOGV("Asynchronous input event injection succeeded.");
4402 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004403 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004404 ALOGW("Asynchronous input event injection failed.");
4405 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004406 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004407 ALOGW("Asynchronous input event injection permission denied.");
4408 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004409 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004410 ALOGW("Asynchronous input event injection timed out.");
4411 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004412 case InputEventInjectionResult::PENDING:
4413 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4414 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004415 }
4416 }
4417
4418 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004419 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004420 }
4421}
4422
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004423void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4424 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004425 if (injectionState) {
4426 injectionState->pendingForegroundDispatches += 1;
4427 }
4428}
4429
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004430void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4431 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004432 if (injectionState) {
4433 injectionState->pendingForegroundDispatches -= 1;
4434
4435 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004436 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004437 }
4438 }
4439}
4440
chaviw98318de2021-05-19 16:45:23 -05004441const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004442 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004443 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004444 auto it = mWindowHandlesByDisplay.find(displayId);
4445 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004446}
4447
chaviw98318de2021-05-19 16:45:23 -05004448sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004449 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004450 if (windowHandleToken == nullptr) {
4451 return nullptr;
4452 }
4453
Arthur Hungb92218b2018-08-14 12:00:21 +08004454 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004455 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4456 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004457 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004458 return windowHandle;
4459 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004460 }
4461 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004462 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004463}
4464
chaviw98318de2021-05-19 16:45:23 -05004465sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4466 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004467 if (windowHandleToken == nullptr) {
4468 return nullptr;
4469 }
4470
chaviw98318de2021-05-19 16:45:23 -05004471 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004472 if (windowHandle->getToken() == windowHandleToken) {
4473 return windowHandle;
4474 }
4475 }
4476 return nullptr;
4477}
4478
chaviw98318de2021-05-19 16:45:23 -05004479sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4480 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004481 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004482 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4483 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004484 if (handle->getId() == windowHandle->getId() &&
4485 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004486 if (windowHandle->getInfo()->displayId != it.first) {
4487 ALOGE("Found window %s in display %" PRId32
4488 ", but it should belong to display %" PRId32,
4489 windowHandle->getName().c_str(), it.first,
4490 windowHandle->getInfo()->displayId);
4491 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004492 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004493 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004494 }
4495 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004496 return nullptr;
4497}
4498
chaviw98318de2021-05-19 16:45:23 -05004499sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004500 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4501 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004502}
4503
chaviw98318de2021-05-19 16:45:23 -05004504bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004505 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4506 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004507 windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004508 if (connection != nullptr && noInputChannel) {
4509 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4510 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4511 return false;
4512 }
4513
4514 if (connection == nullptr) {
4515 if (!noInputChannel) {
4516 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4517 }
4518 return false;
4519 }
4520 if (!connection->responsive) {
4521 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4522 return false;
4523 }
4524 return true;
4525}
4526
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004527std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4528 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004529 auto connectionIt = mConnectionsByToken.find(token);
4530 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004531 return nullptr;
4532 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004533 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004534}
4535
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004536void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004537 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4538 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004539 // Remove all handles on a display if there are no windows left.
4540 mWindowHandlesByDisplay.erase(displayId);
4541 return;
4542 }
4543
4544 // Since we compare the pointer of input window handles across window updates, we need
4545 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004546 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4547 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4548 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004549 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004550 }
4551
chaviw98318de2021-05-19 16:45:23 -05004552 std::vector<sp<WindowInfoHandle>> newHandles;
4553 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05004554 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004555 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004556 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004557 info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
4558 const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
4559 !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004560 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004561 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004562 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004563 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004564 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004565 }
4566
4567 if (info->displayId != displayId) {
4568 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4569 handle->getName().c_str(), displayId, info->displayId);
4570 continue;
4571 }
4572
Robert Carredd13602020-04-13 17:24:34 -07004573 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4574 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004575 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004576 oldHandle->updateFrom(handle);
4577 newHandles.push_back(oldHandle);
4578 } else {
4579 newHandles.push_back(handle);
4580 }
4581 }
4582
4583 // Insert or replace
4584 mWindowHandlesByDisplay[displayId] = newHandles;
4585}
4586
Arthur Hung72d8dc32020-03-28 00:48:39 +00004587void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004588 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07004589 // TODO(b/198444055): Remove setInputWindows from InputDispatcher.
Arthur Hung72d8dc32020-03-28 00:48:39 +00004590 { // acquire lock
4591 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004592 for (const auto& [displayId, handles] : handlesPerDisplay) {
4593 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004594 }
4595 }
4596 // Wake up poll loop since it may need to make new input dispatching choices.
4597 mLooper->wake();
4598}
4599
Arthur Hungb92218b2018-08-14 12:00:21 +08004600/**
4601 * Called from InputManagerService, update window handle list by displayId that can receive input.
4602 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4603 * If set an empty list, remove all handles from the specific display.
4604 * For focused handle, check if need to change and send a cancel event to previous one.
4605 * For removed handle, check if need to send a cancel event if already in touch.
4606 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004607void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004608 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004609 if (DEBUG_FOCUS) {
4610 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004611 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004612 windowList += iwh->getName() + " ";
4613 }
4614 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4615 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004616
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004617 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
chaviw98318de2021-05-19 16:45:23 -05004618 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004619 const bool noInputWindow =
chaviw98318de2021-05-19 16:45:23 -05004620 window->getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004621 if (noInputWindow && window->getToken() != nullptr) {
4622 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4623 window->getName().c_str());
4624 window->releaseChannel();
4625 }
4626 }
4627
Arthur Hung72d8dc32020-03-28 00:48:39 +00004628 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004629 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004630
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004631 // Save the old windows' orientation by ID before it gets updated.
4632 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004633 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004634 oldWindowOrientations.emplace(handle->getId(),
4635 handle->getInfo()->transform.getOrientation());
4636 }
4637
chaviw98318de2021-05-19 16:45:23 -05004638 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004639
chaviw98318de2021-05-19 16:45:23 -05004640 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004641 if (mLastHoverWindowHandle &&
4642 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4643 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004644 mLastHoverWindowHandle = nullptr;
4645 }
4646
Vishnu Nairc519ff72021-01-21 08:23:08 -08004647 std::optional<FocusResolver::FocusChanges> changes =
4648 mFocusResolver.setInputWindows(displayId, windowHandles);
4649 if (changes) {
4650 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004651 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004652
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004653 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4654 mTouchStatesByDisplay.find(displayId);
4655 if (stateIt != mTouchStatesByDisplay.end()) {
4656 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004657 for (size_t i = 0; i < state.windows.size();) {
4658 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004659 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004660 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004661 ALOGD("Touched window was removed: %s in display %" PRId32,
4662 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004663 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004664 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004665 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4666 if (touchedInputChannel != nullptr) {
4667 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4668 "touched window was removed");
4669 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004670 // Since we are about to drop the touch, cancel the events for the wallpaper as
4671 // well.
4672 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND &&
4673 touchedWindow.windowHandle->getInfo()->hasWallpaper) {
4674 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
4675 if (wallpaper != nullptr) {
4676 sp<Connection> wallpaperConnection =
4677 getConnectionLocked(wallpaper->getToken());
4678 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection,
4679 options);
4680 }
4681 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004682 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004683 state.windows.erase(state.windows.begin() + i);
4684 } else {
4685 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004686 }
4687 }
arthurhungb89ccb02020-12-30 16:19:01 +08004688
arthurhung6d4bed92021-03-17 11:59:33 +08004689 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004690 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004691 if (mDragState &&
4692 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004693 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004694 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004695 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004696 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004697
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004698 if (isPerWindowInputRotationEnabled()) {
4699 // Determine if the orientation of any of the input windows have changed, and cancel all
4700 // pointer events if necessary.
chaviw98318de2021-05-19 16:45:23 -05004701 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4702 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004703 if (newWindowHandle != nullptr &&
4704 newWindowHandle->getInfo()->transform.getOrientation() !=
4705 oldWindowOrientations[oldWindowHandle->getId()]) {
4706 std::shared_ptr<InputChannel> inputChannel =
4707 getInputChannelLocked(newWindowHandle->getToken());
4708 if (inputChannel != nullptr) {
4709 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4710 "touched window's orientation changed");
4711 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4712 }
4713 }
4714 }
4715 }
4716
Arthur Hung72d8dc32020-03-28 00:48:39 +00004717 // Release information for windows that are no longer present.
4718 // This ensures that unused input channels are released promptly.
4719 // Otherwise, they might stick around until the window handle is destroyed
4720 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004721 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004722 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004723 if (DEBUG_FOCUS) {
4724 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004725 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004726 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004727 // To avoid making too many calls into the compat framework, only
4728 // check for window flags when windows are going away.
4729 // TODO(b/157929241) : delete this. This is only needed temporarily
4730 // in order to gather some data about the flag usage
chaviw98318de2021-05-19 16:45:23 -05004731 if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004732 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4733 oldWindowHandle->getName().c_str());
4734 if (mCompatService != nullptr) {
4735 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4736 oldWindowHandle->getInfo()->ownerUid);
4737 }
4738 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004739 }
chaviw291d88a2019-02-14 10:33:58 -08004740 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004741}
4742
4743void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004744 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004745 if (DEBUG_FOCUS) {
4746 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4747 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4748 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004749 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004750 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004751 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004752 } // release lock
4753
4754 // Wake up poll loop since it may need to make new input dispatching choices.
4755 mLooper->wake();
4756}
4757
Vishnu Nair599f1412021-06-21 10:39:58 -07004758void InputDispatcher::setFocusedApplicationLocked(
4759 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4760 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4761 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4762
4763 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4764 return; // This application is already focused. No need to wake up or change anything.
4765 }
4766
4767 // Set the new application handle.
4768 if (inputApplicationHandle != nullptr) {
4769 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4770 } else {
4771 mFocusedApplicationHandlesByDisplay.erase(displayId);
4772 }
4773
4774 // No matter what the old focused application was, stop waiting on it because it is
4775 // no longer focused.
4776 resetNoFocusedWindowTimeoutLocked();
4777}
4778
Tiger Huang721e26f2018-07-24 22:26:19 +08004779/**
4780 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4781 * the display not specified.
4782 *
4783 * We track any unreleased events for each window. If a window loses the ability to receive the
4784 * released event, we will send a cancel event to it. So when the focused display is changed, we
4785 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4786 * display. The display-specified events won't be affected.
4787 */
4788void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004789 if (DEBUG_FOCUS) {
4790 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4791 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004792 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004793 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004794
4795 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004796 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004797 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004798 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004799 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004800 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004801 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004802 CancelationOptions
4803 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4804 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004805 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004806 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4807 }
4808 }
4809 mFocusedDisplayId = displayId;
4810
Chris Ye3c2d6f52020-08-09 10:39:48 -07004811 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004812 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004813 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004814
Vishnu Nairad321cd2020-08-20 16:40:21 -07004815 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004816 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004817 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004818 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004819 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004820 }
4821 }
4822 }
4823
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004824 if (DEBUG_FOCUS) {
4825 logDispatchStateLocked();
4826 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004827 } // release lock
4828
4829 // Wake up poll loop since it may need to make new input dispatching choices.
4830 mLooper->wake();
4831}
4832
Michael Wrightd02c5b62014-02-10 15:10:22 -08004833void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004834 if (DEBUG_FOCUS) {
4835 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4836 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004837
4838 bool changed;
4839 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004840 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004841
4842 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4843 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004844 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004845 }
4846
4847 if (mDispatchEnabled && !enabled) {
4848 resetAndDropEverythingLocked("dispatcher is being disabled");
4849 }
4850
4851 mDispatchEnabled = enabled;
4852 mDispatchFrozen = frozen;
4853 changed = true;
4854 } else {
4855 changed = false;
4856 }
4857
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004858 if (DEBUG_FOCUS) {
4859 logDispatchStateLocked();
4860 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004861 } // release lock
4862
4863 if (changed) {
4864 // Wake up poll loop since it may need to make new input dispatching choices.
4865 mLooper->wake();
4866 }
4867}
4868
4869void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004870 if (DEBUG_FOCUS) {
4871 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4872 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004873
4874 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004875 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004876
4877 if (mInputFilterEnabled == enabled) {
4878 return;
4879 }
4880
4881 mInputFilterEnabled = enabled;
4882 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4883 } // release lock
4884
4885 // Wake up poll loop since there might be work to do to drop everything.
4886 mLooper->wake();
4887}
4888
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004889void InputDispatcher::setInTouchMode(bool inTouchMode) {
4890 std::scoped_lock lock(mLock);
4891 mInTouchMode = inTouchMode;
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004892 // TODO(b/193718270): Fire TouchModeEvent here.
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004893}
4894
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004895void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4896 if (opacity < 0 || opacity > 1) {
4897 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4898 return;
4899 }
4900
4901 std::scoped_lock lock(mLock);
4902 mMaximumObscuringOpacityForTouch = opacity;
4903}
4904
4905void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4906 std::scoped_lock lock(mLock);
4907 mBlockUntrustedTouchesMode = mode;
4908}
4909
Arthur Hungabbb9d82021-09-01 14:52:30 +00004910std::pair<TouchState*, TouchedWindow*> InputDispatcher::findTouchStateAndWindowLocked(
4911 const sp<IBinder>& token) {
4912 for (auto& [displayId, state] : mTouchStatesByDisplay) {
4913 for (TouchedWindow& w : state.windows) {
4914 if (w.windowHandle->getToken() == token) {
4915 return std::make_pair(&state, &w);
4916 }
4917 }
4918 }
4919 return std::make_pair(nullptr, nullptr);
4920}
4921
arthurhungb89ccb02020-12-30 16:19:01 +08004922bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4923 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004924 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004925 if (DEBUG_FOCUS) {
4926 ALOGD("Trivial transfer to same window.");
4927 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004928 return true;
4929 }
4930
Michael Wrightd02c5b62014-02-10 15:10:22 -08004931 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004932 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004933
Arthur Hungabbb9d82021-09-01 14:52:30 +00004934 // Find the target touch state and touched window by fromToken.
4935 auto [state, touchedWindow] = findTouchStateAndWindowLocked(fromToken);
4936 if (state == nullptr || touchedWindow == nullptr) {
4937 ALOGD("Focus transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004938 return false;
4939 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00004940
4941 const int32_t displayId = state->displayId;
4942 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
4943 if (toWindowHandle == nullptr) {
4944 ALOGW("Cannot transfer focus because to window not found.");
4945 return false;
4946 }
4947
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004948 if (DEBUG_FOCUS) {
4949 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00004950 touchedWindow->windowHandle->getName().c_str(),
4951 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004952 }
4953
Arthur Hungabbb9d82021-09-01 14:52:30 +00004954 // Erase old window.
4955 int32_t oldTargetFlags = touchedWindow->targetFlags;
4956 BitSet32 pointerIds = touchedWindow->pointerIds;
4957 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004958
Arthur Hungabbb9d82021-09-01 14:52:30 +00004959 // Add new window.
4960 int32_t newTargetFlags = oldTargetFlags &
4961 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4962 InputTarget::FLAG_DISPATCH_AS_IS);
4963 state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004964
Arthur Hungabbb9d82021-09-01 14:52:30 +00004965 // Store the dragging window.
4966 if (isDragDrop) {
4967 mDragState = std::make_unique<DragState>(toWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004968 }
4969
Arthur Hungabbb9d82021-09-01 14:52:30 +00004970 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004971 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4972 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004973 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004974 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004975 CancelationOptions
4976 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4977 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004978 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004979 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004980 }
4981
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004982 if (DEBUG_FOCUS) {
4983 logDispatchStateLocked();
4984 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004985 } // release lock
4986
4987 // Wake up poll loop since it may need to make new input dispatching choices.
4988 mLooper->wake();
4989 return true;
4990}
4991
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00004992// Binder call
4993bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
4994 sp<IBinder> fromToken;
4995 { // acquire lock
4996 std::scoped_lock _l(mLock);
4997
Arthur Hungabbb9d82021-09-01 14:52:30 +00004998 auto it = std::find_if(mTouchStatesByDisplay.begin(), mTouchStatesByDisplay.end(),
4999 [](const auto& pair) { return pair.second.windows.size() == 1; });
5000 if (it == mTouchStatesByDisplay.end()) {
5001 ALOGW("Cannot transfer touch state because there is no exact window being touched");
5002 return false;
5003 }
5004 const int32_t displayId = it->first;
5005 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005006 if (toWindowHandle == nullptr) {
5007 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
5008 return false;
5009 }
5010
Arthur Hungabbb9d82021-09-01 14:52:30 +00005011 TouchState& state = it->second;
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005012 const TouchedWindow& touchedWindow = state.windows[0];
5013 fromToken = touchedWindow.windowHandle->getToken();
5014 } // release lock
5015
5016 return transferTouchFocus(fromToken, destChannelToken);
5017}
5018
Michael Wrightd02c5b62014-02-10 15:10:22 -08005019void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005020 if (DEBUG_FOCUS) {
5021 ALOGD("Resetting and dropping all events (%s).", reason);
5022 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005023
5024 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
5025 synthesizeCancelationEventsForAllConnectionsLocked(options);
5026
5027 resetKeyRepeatLocked();
5028 releasePendingEventLocked();
5029 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005030 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005031
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005032 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005033 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005034 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07005035 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005036}
5037
5038void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005039 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005040 dumpDispatchStateLocked(dump);
5041
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005042 std::istringstream stream(dump);
5043 std::string line;
5044
5045 while (std::getline(stream, line, '\n')) {
5046 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005047 }
5048}
5049
Prabir Pradhan99987712020-11-10 18:43:05 -08005050std::string InputDispatcher::dumpPointerCaptureStateLocked() {
5051 std::string dump;
5052
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005053 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5054 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005055
5056 std::string windowName = "None";
5057 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005058 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005059 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5060 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5061 : "token has capture without window";
5062 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005063 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005064
5065 return dump;
5066}
5067
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005068void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005069 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5070 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5071 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005072 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005073
Tiger Huang721e26f2018-07-24 22:26:19 +08005074 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5075 dump += StringPrintf(INDENT "FocusedApplications:\n");
5076 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5077 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005078 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005079 const std::chrono::duration timeout =
5080 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005081 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005082 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005083 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005084 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005085 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005086 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005087 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005088
Vishnu Nairc519ff72021-01-21 08:23:08 -08005089 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005090 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005091
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005092 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005093 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005094 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
5095 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005096 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005097 state.displayId, toString(state.down), toString(state.split),
5098 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005099 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005100 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005101 for (size_t i = 0; i < state.windows.size(); i++) {
5102 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005103 dump += StringPrintf(INDENT4
5104 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
5105 i, touchedWindow.windowHandle->getName().c_str(),
5106 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005107 }
5108 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005109 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005110 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005111 }
5112 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005113 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005114 }
5115
arthurhung6d4bed92021-03-17 11:59:33 +08005116 if (mDragState) {
5117 dump += StringPrintf(INDENT "DragState:\n");
5118 mDragState->dump(dump, INDENT2);
5119 }
5120
Arthur Hungb92218b2018-08-14 12:00:21 +08005121 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005122 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5123 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5124 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5125 const auto& displayInfo = it->second;
5126 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5127 displayInfo.logicalHeight);
5128 displayInfo.transform.dump(dump, "transform", INDENT4);
5129 } else {
5130 dump += INDENT2 "No DisplayInfo found!\n";
5131 }
5132
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005133 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005134 dump += INDENT2 "Windows:\n";
5135 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005136 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5137 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005138
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005139 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005140 "paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005141 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005142 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005143 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005144 "applicationInfo.name=%s, "
5145 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005146 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005147 i, windowInfo->name.c_str(), windowInfo->id,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005148 windowInfo->displayId, toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07005149 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005150 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005151 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01005152 windowInfo->flags.string().c_str(),
Dominik Laskowski75788452021-02-09 18:51:25 -08005153 ftl::enum_string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01005154 windowInfo->frameLeft, windowInfo->frameTop,
5155 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005156 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005157 windowInfo->applicationInfo.name.c_str(),
5158 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005159 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01005160 dump += StringPrintf(", inputFeatures=%s",
5161 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005162 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005163 "ms, trustedOverlay=%s, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005164 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005165 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005166 millis(windowInfo->dispatchingTimeout),
5167 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005168 toString(windowInfo->token != nullptr),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005169 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005170 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005171 }
5172 } else {
5173 dump += INDENT2 "Windows: <none>\n";
5174 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005175 }
5176 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005177 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005178 }
5179
Michael Wright3dd60e22019-03-27 22:06:44 +00005180 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005181 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005182 const std::vector<Monitor>& monitors = it.second;
5183 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
5184 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005185 }
5186 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005187 const std::vector<Monitor>& monitors = it.second;
5188 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
5189 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005190 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005191 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00005192 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005193 }
5194
5195 nsecs_t currentTime = now();
5196
5197 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005198 if (!mRecentQueue.empty()) {
5199 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005200 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005201 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005202 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005203 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005204 }
5205 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005206 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005207 }
5208
5209 // Dump event currently being dispatched.
5210 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005211 dump += INDENT "PendingEvent:\n";
5212 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005213 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005214 dump += StringPrintf(", age=%" PRId64 "ms\n",
5215 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005216 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005217 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005218 }
5219
5220 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005221 if (!mInboundQueue.empty()) {
5222 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005223 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005224 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005225 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005226 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005227 }
5228 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005229 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005230 }
5231
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005232 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005233 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005234 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5235 const KeyReplacement& replacement = pair.first;
5236 int32_t newKeyCode = pair.second;
5237 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005238 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005239 }
5240 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005241 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005242 }
5243
Prabir Pradhancef936d2021-07-21 16:17:52 +00005244 if (!mCommandQueue.empty()) {
5245 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5246 } else {
5247 dump += INDENT "CommandQueue: <empty>\n";
5248 }
5249
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005250 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005251 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005252 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005253 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005254 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005255 connection->inputChannel->getFd().get(),
5256 connection->getInputChannelName().c_str(),
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005257 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005258 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005259
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005260 if (!connection->outboundQueue.empty()) {
5261 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5262 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005263 dump += dumpQueue(connection->outboundQueue, currentTime);
5264
Michael Wrightd02c5b62014-02-10 15:10:22 -08005265 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005266 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005267 }
5268
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005269 if (!connection->waitQueue.empty()) {
5270 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5271 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005272 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005273 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005274 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005275 }
5276 }
5277 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005278 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005279 }
5280
5281 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005282 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5283 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005284 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005285 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005286 }
5287
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005288 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005289 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5290 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5291 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005292 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005293 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005294}
5295
Michael Wright3dd60e22019-03-27 22:06:44 +00005296void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5297 const size_t numMonitors = monitors.size();
5298 for (size_t i = 0; i < numMonitors; i++) {
5299 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005300 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005301 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5302 dump += "\n";
5303 }
5304}
5305
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005306class LooperEventCallback : public LooperCallback {
5307public:
5308 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5309 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5310
5311private:
5312 std::function<int(int events)> mCallback;
5313};
5314
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005315Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005316 if (DEBUG_CHANNEL_CREATION) {
5317 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5318 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005319
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005320 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005321 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005322 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005323
5324 if (result) {
5325 return base::Error(result) << "Failed to open input channel pair with name " << name;
5326 }
5327
Michael Wrightd02c5b62014-02-10 15:10:22 -08005328 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005329 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005330 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005331 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005332 sp<Connection> connection =
5333 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005334
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005335 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5336 ALOGE("Created a new connection, but the token %p is already known", token.get());
5337 }
5338 mConnectionsByToken.emplace(token, connection);
5339
5340 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5341 this, std::placeholders::_1, token);
5342
5343 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005344 } // release lock
5345
5346 // Wake the looper because some connections have changed.
5347 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005348 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005349}
5350
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005351Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5352 bool isGestureMonitor,
5353 const std::string& name,
5354 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005355 std::shared_ptr<InputChannel> serverChannel;
5356 std::unique_ptr<InputChannel> clientChannel;
5357 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5358 if (result) {
5359 return base::Error(result) << "Failed to open input channel pair with name " << name;
5360 }
5361
Michael Wright3dd60e22019-03-27 22:06:44 +00005362 { // acquire lock
5363 std::scoped_lock _l(mLock);
5364
5365 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005366 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5367 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005368 }
5369
Garfield Tan15601662020-09-22 15:32:38 -07005370 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005371 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005372 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005373
5374 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5375 ALOGE("Created a new connection, but the token %p is already known", token.get());
5376 }
5377 mConnectionsByToken.emplace(token, connection);
5378 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5379 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005380
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005381 auto& monitorsByDisplay =
5382 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005383 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005384
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005385 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Siarhei Vishniakouc961c742021-05-19 19:16:59 +00005386 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5387 displayId, toString(isGestureMonitor), pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005388 }
Garfield Tan15601662020-09-22 15:32:38 -07005389
Michael Wright3dd60e22019-03-27 22:06:44 +00005390 // Wake the looper because some connections have changed.
5391 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005392 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005393}
5394
Garfield Tan15601662020-09-22 15:32:38 -07005395status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005396 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005397 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005398
Garfield Tan15601662020-09-22 15:32:38 -07005399 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005400 if (status) {
5401 return status;
5402 }
5403 } // release lock
5404
5405 // Wake the poll loop because removing the connection may have changed the current
5406 // synchronization state.
5407 mLooper->wake();
5408 return OK;
5409}
5410
Garfield Tan15601662020-09-22 15:32:38 -07005411status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5412 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005413 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005414 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005415 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005416 return BAD_VALUE;
5417 }
5418
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005419 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005420
Michael Wrightd02c5b62014-02-10 15:10:22 -08005421 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005422 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005423 }
5424
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005425 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005426
5427 nsecs_t currentTime = now();
5428 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5429
5430 connection->status = Connection::STATUS_ZOMBIE;
5431 return OK;
5432}
5433
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005434void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5435 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5436 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005437}
5438
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005439void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005440 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005441 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005442 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005443 std::vector<Monitor>& monitors = it->second;
5444 const size_t numMonitors = monitors.size();
5445 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005446 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005447 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5448 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005449 monitors.erase(monitors.begin() + i);
5450 break;
5451 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005452 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005453 if (monitors.empty()) {
5454 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005455 } else {
5456 ++it;
5457 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005458 }
5459}
5460
Michael Wright3dd60e22019-03-27 22:06:44 +00005461status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5462 { // acquire lock
5463 std::scoped_lock _l(mLock);
5464 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5465
5466 if (!foundDisplayId) {
5467 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5468 return BAD_VALUE;
5469 }
5470 int32_t displayId = foundDisplayId.value();
5471
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005472 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5473 mTouchStatesByDisplay.find(displayId);
5474 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005475 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5476 return BAD_VALUE;
5477 }
5478
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005479 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005480 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005481 std::optional<int32_t> foundDeviceId;
5482 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005483 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005484 requestingChannel = touchedMonitor.monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005485 foundDeviceId = state.deviceId;
5486 }
5487 }
5488 if (!foundDeviceId || !state.down) {
5489 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005490 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005491 return BAD_VALUE;
5492 }
5493 int32_t deviceId = foundDeviceId.value();
5494
5495 // Send cancel events to all the input channels we're stealing from.
5496 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005497 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005498 options.deviceId = deviceId;
5499 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005500 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005501 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005502 std::shared_ptr<InputChannel> channel =
5503 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005504 if (channel != nullptr) {
5505 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005506 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005507 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005508 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005509 canceledWindows += "]";
5510 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5511 canceledWindows.c_str());
5512
Michael Wright3dd60e22019-03-27 22:06:44 +00005513 // Then clear the current touch state so we stop dispatching to them as well.
5514 state.filterNonMonitors();
5515 }
5516 return OK;
5517}
5518
Prabir Pradhan99987712020-11-10 18:43:05 -08005519void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5520 { // acquire lock
5521 std::scoped_lock _l(mLock);
5522 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005523 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005524 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5525 windowHandle != nullptr ? windowHandle->getName().c_str()
5526 : "token without window");
5527 }
5528
Vishnu Nairc519ff72021-01-21 08:23:08 -08005529 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005530 if (focusedToken != windowToken) {
5531 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5532 enabled ? "enable" : "disable");
5533 return;
5534 }
5535
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005536 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08005537 ALOGW("Ignoring request to %s Pointer Capture: "
5538 "window has %s requested pointer capture.",
5539 enabled ? "enable" : "disable", enabled ? "already" : "not");
5540 return;
5541 }
5542
Prabir Pradhan99987712020-11-10 18:43:05 -08005543 setPointerCaptureLocked(enabled);
5544 } // release lock
5545
5546 // Wake the thread to process command entries.
5547 mLooper->wake();
5548}
5549
Michael Wright3dd60e22019-03-27 22:06:44 +00005550std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5551 const sp<IBinder>& token) {
5552 for (const auto& it : mGestureMonitorsByDisplay) {
5553 const std::vector<Monitor>& monitors = it.second;
5554 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005555 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005556 return it.first;
5557 }
5558 }
5559 }
5560 return std::nullopt;
5561}
5562
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005563std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5564 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5565 if (gesturePid.has_value()) {
5566 return gesturePid;
5567 }
5568 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5569}
5570
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005571sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005572 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005573 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005574 }
5575
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005576 for (const auto& [token, connection] : mConnectionsByToken) {
5577 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005578 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005579 }
5580 }
Robert Carr4e670e52018-08-15 13:26:12 -07005581
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005582 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005583}
5584
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005585std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5586 sp<Connection> connection = getConnectionLocked(connectionToken);
5587 if (connection == nullptr) {
5588 return "<nullptr>";
5589 }
5590 return connection->getInputChannelName();
5591}
5592
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005593void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005594 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005595 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005596}
5597
Prabir Pradhancef936d2021-07-21 16:17:52 +00005598void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5599 const sp<Connection>& connection, uint32_t seq,
5600 bool handled, nsecs_t consumeTime) {
5601 // Handle post-event policy actions.
5602 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5603 if (dispatchEntryIt == connection->waitQueue.end()) {
5604 return;
5605 }
5606 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5607 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5608 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5609 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5610 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5611 }
5612 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5613 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5614 connection->inputChannel->getConnectionToken(),
5615 dispatchEntry->deliveryTime, consumeTime, finishTime);
5616 }
5617
5618 bool restartEvent;
5619 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5620 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5621 restartEvent =
5622 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5623 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5624 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5625 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5626 handled);
5627 } else {
5628 restartEvent = false;
5629 }
5630
5631 // Dequeue the event and start the next cycle.
5632 // Because the lock might have been released, it is possible that the
5633 // contents of the wait queue to have been drained, so we need to double-check
5634 // a few things.
5635 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5636 if (dispatchEntryIt != connection->waitQueue.end()) {
5637 dispatchEntry = *dispatchEntryIt;
5638 connection->waitQueue.erase(dispatchEntryIt);
5639 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5640 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5641 if (!connection->responsive) {
5642 connection->responsive = isConnectionResponsive(*connection);
5643 if (connection->responsive) {
5644 // The connection was unresponsive, and now it's responsive.
5645 processConnectionResponsiveLocked(*connection);
5646 }
5647 }
5648 traceWaitQueueLength(*connection);
5649 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
5650 connection->outboundQueue.push_front(dispatchEntry);
5651 traceOutboundQueueLength(*connection);
5652 } else {
5653 releaseDispatchEntry(dispatchEntry);
5654 }
5655 }
5656
5657 // Start the next dispatch cycle for this connection.
5658 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005659}
5660
Prabir Pradhancef936d2021-07-21 16:17:52 +00005661void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5662 const sp<IBinder>& newToken) {
5663 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5664 scoped_unlock unlock(mLock);
5665 mPolicy->notifyFocusChanged(oldToken, newToken);
5666 };
5667 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005668}
5669
Prabir Pradhancef936d2021-07-21 16:17:52 +00005670void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5671 auto command = [this, token, x, y]() REQUIRES(mLock) {
5672 scoped_unlock unlock(mLock);
5673 mPolicy->notifyDropWindow(token, x, y);
5674 };
5675 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005676}
5677
Prabir Pradhancef936d2021-07-21 16:17:52 +00005678void InputDispatcher::sendUntrustedTouchCommandLocked(const std::string& obscuringPackage) {
5679 auto command = [this, obscuringPackage]() REQUIRES(mLock) {
5680 scoped_unlock unlock(mLock);
5681 mPolicy->notifyUntrustedTouch(obscuringPackage);
5682 };
5683 postCommandLocked(std::move(command));
arthurhungf452d0b2021-01-06 00:19:52 +08005684}
5685
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005686void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5687 if (connection == nullptr) {
5688 LOG_ALWAYS_FATAL("Caller must check for nullness");
5689 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005690 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5691 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005692 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005693 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005694 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005695 return;
5696 }
5697 /**
5698 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5699 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5700 * has changed. This could cause newer entries to time out before the already dispatched
5701 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5702 * processes the events linearly. So providing information about the oldest entry seems to be
5703 * most useful.
5704 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005705 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005706 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5707 std::string reason =
5708 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005709 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005710 ns2ms(currentWait),
5711 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005712 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005713 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005714
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005715 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5716
5717 // Stop waking up for events on this connection, it is already unresponsive
5718 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005719}
5720
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005721void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5722 std::string reason =
5723 StringPrintf("%s does not have a focused window", application->getName().c_str());
5724 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005725
Prabir Pradhancef936d2021-07-21 16:17:52 +00005726 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5727 scoped_unlock unlock(mLock);
5728 mPolicy->notifyNoFocusedWindowAnr(application);
5729 };
5730 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005731}
5732
chaviw98318de2021-05-19 16:45:23 -05005733void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005734 const std::string& reason) {
5735 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5736 updateLastAnrStateLocked(windowLabel, reason);
5737}
5738
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005739void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5740 const std::string& reason) {
5741 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005742 updateLastAnrStateLocked(windowLabel, reason);
5743}
5744
5745void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5746 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005747 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005748 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005749 struct tm tm;
5750 localtime_r(&t, &tm);
5751 char timestr[64];
5752 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005753 mLastAnrState.clear();
5754 mLastAnrState += INDENT "ANR:\n";
5755 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005756 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5757 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005758 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005759}
5760
Prabir Pradhancef936d2021-07-21 16:17:52 +00005761void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5762 KeyEntry& entry) {
5763 const KeyEvent event = createKeyEvent(entry);
5764 nsecs_t delay = 0;
5765 { // release lock
5766 scoped_unlock unlock(mLock);
5767 android::base::Timer t;
5768 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5769 entry.policyFlags);
5770 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5771 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5772 std::to_string(t.duration().count()).c_str());
5773 }
5774 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005775
5776 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005777 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005778 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005779 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005780 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005781 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5782 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005783 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005784}
5785
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005786void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005787 auto command = [this, pid, reason = std::move(reason)]() REQUIRES(mLock) {
5788 scoped_unlock unlock(mLock);
5789 mPolicy->notifyMonitorUnresponsive(pid, reason);
5790 };
5791 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005792}
5793
Prabir Pradhancef936d2021-07-21 16:17:52 +00005794void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005795 std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005796 auto command = [this, token, reason = std::move(reason)]() REQUIRES(mLock) {
5797 scoped_unlock unlock(mLock);
5798 mPolicy->notifyWindowUnresponsive(token, reason);
5799 };
5800 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005801}
5802
5803void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005804 auto command = [this, pid]() REQUIRES(mLock) {
5805 scoped_unlock unlock(mLock);
5806 mPolicy->notifyMonitorResponsive(pid);
5807 };
5808 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005809}
5810
Prabir Pradhancef936d2021-07-21 16:17:52 +00005811void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) {
5812 auto command = [this, connectionToken]() REQUIRES(mLock) {
5813 scoped_unlock unlock(mLock);
5814 mPolicy->notifyWindowResponsive(connectionToken);
5815 };
5816 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005817}
5818
5819/**
5820 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5821 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5822 * command entry to the command queue.
5823 */
5824void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5825 std::string reason) {
5826 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5827 if (connection.monitor) {
5828 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5829 reason.c_str());
5830 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5831 if (!pid.has_value()) {
5832 ALOGE("Could not find unresponsive monitor for connection %s",
5833 connection.inputChannel->getName().c_str());
5834 return;
5835 }
5836 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5837 return;
5838 }
5839 // If not a monitor, must be a window
5840 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5841 reason.c_str());
5842 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5843}
5844
5845/**
5846 * Tell the policy that a connection has become responsive so that it can stop ANR.
5847 */
5848void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5849 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5850 if (connection.monitor) {
5851 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5852 if (!pid.has_value()) {
5853 ALOGE("Could not find responsive monitor for connection %s",
5854 connection.inputChannel->getName().c_str());
5855 return;
5856 }
5857 sendMonitorResponsiveCommandLocked(pid.value());
5858 return;
5859 }
5860 // If not a monitor, must be a window
5861 sendWindowResponsiveCommandLocked(connectionToken);
5862}
5863
Prabir Pradhancef936d2021-07-21 16:17:52 +00005864bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005865 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005866 KeyEntry& keyEntry, bool handled) {
5867 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005868 if (!handled) {
5869 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005870 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005871 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005872 return false;
5873 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005874
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005875 // Get the fallback key state.
5876 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005877 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005878 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005879 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005880 connection->inputState.removeFallbackKey(originalKeyCode);
5881 }
5882
5883 if (handled || !dispatchEntry->hasForegroundTarget()) {
5884 // If the application handles the original key for which we previously
5885 // generated a fallback or if the window is not a foreground window,
5886 // then cancel the associated fallback key, if any.
5887 if (fallbackKeyCode != -1) {
5888 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005889 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5890 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
5891 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5892 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
5893 keyEntry.policyFlags);
5894 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005895 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005896 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005897
5898 mLock.unlock();
5899
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005900 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005901 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005902
5903 mLock.lock();
5904
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005905 // Cancel the fallback key.
5906 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005907 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005908 "application handled the original non-fallback key "
5909 "or is no longer a foreground target, "
5910 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005911 options.keyCode = fallbackKeyCode;
5912 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005913 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005914 connection->inputState.removeFallbackKey(originalKeyCode);
5915 }
5916 } else {
5917 // If the application did not handle a non-fallback key, first check
5918 // that we are in a good state to perform unhandled key event processing
5919 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005920 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005921 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005922 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5923 ALOGD("Unhandled key event: Skipping unhandled key event processing "
5924 "since this is not an initial down. "
5925 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5926 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5927 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005928 return false;
5929 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005930
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005931 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005932 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5933 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
5934 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5935 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5936 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005937 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005938
5939 mLock.unlock();
5940
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005941 bool fallback =
5942 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005943 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005944
5945 mLock.lock();
5946
5947 if (connection->status != Connection::STATUS_NORMAL) {
5948 connection->inputState.removeFallbackKey(originalKeyCode);
5949 return false;
5950 }
5951
5952 // Latch the fallback keycode for this key on an initial down.
5953 // The fallback keycode cannot change at any other point in the lifecycle.
5954 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005955 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005956 fallbackKeyCode = event.getKeyCode();
5957 } else {
5958 fallbackKeyCode = AKEYCODE_UNKNOWN;
5959 }
5960 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5961 }
5962
5963 ALOG_ASSERT(fallbackKeyCode != -1);
5964
5965 // Cancel the fallback key if the policy decides not to send it anymore.
5966 // We will continue to dispatch the key to the policy but we will no
5967 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005968 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5969 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005970 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5971 if (fallback) {
5972 ALOGD("Unhandled key event: Policy requested to send key %d"
5973 "as a fallback for %d, but on the DOWN it had requested "
5974 "to send %d instead. Fallback canceled.",
5975 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
5976 } else {
5977 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
5978 "but on the DOWN it had requested to send %d. "
5979 "Fallback canceled.",
5980 originalKeyCode, fallbackKeyCode);
5981 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005982 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005983
5984 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5985 "canceling fallback, policy no longer desires it");
5986 options.keyCode = fallbackKeyCode;
5987 synthesizeCancelationEventsForConnectionLocked(connection, options);
5988
5989 fallback = false;
5990 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005991 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005992 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005993 }
5994 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005995
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005996 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5997 {
5998 std::string msg;
5999 const KeyedVector<int32_t, int32_t>& fallbackKeys =
6000 connection->inputState.getFallbackKeys();
6001 for (size_t i = 0; i < fallbackKeys.size(); i++) {
6002 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
6003 }
6004 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6005 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006006 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006007 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006008
6009 if (fallback) {
6010 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006011 keyEntry.eventTime = event.getEventTime();
6012 keyEntry.deviceId = event.getDeviceId();
6013 keyEntry.source = event.getSource();
6014 keyEntry.displayId = event.getDisplayId();
6015 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
6016 keyEntry.keyCode = fallbackKeyCode;
6017 keyEntry.scanCode = event.getScanCode();
6018 keyEntry.metaState = event.getMetaState();
6019 keyEntry.repeatCount = event.getRepeatCount();
6020 keyEntry.downTime = event.getDownTime();
6021 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006022
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006023 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6024 ALOGD("Unhandled key event: Dispatching fallback key. "
6025 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
6026 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
6027 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006028 return true; // restart the event
6029 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006030 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6031 ALOGD("Unhandled key event: No fallback key.");
6032 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006033
6034 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006035 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006036 }
6037 }
6038 return false;
6039}
6040
Prabir Pradhancef936d2021-07-21 16:17:52 +00006041bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006042 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006043 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006044 return false;
6045}
6046
Michael Wrightd02c5b62014-02-10 15:10:22 -08006047void InputDispatcher::traceInboundQueueLengthLocked() {
6048 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006049 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006050 }
6051}
6052
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006053void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006054 if (ATRACE_ENABLED()) {
6055 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006056 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6057 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006058 }
6059}
6060
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006061void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006062 if (ATRACE_ENABLED()) {
6063 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006064 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6065 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006066 }
6067}
6068
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006069void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006070 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006071
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006072 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006073 dumpDispatchStateLocked(dump);
6074
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006075 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006076 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006077 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006078 }
6079}
6080
6081void InputDispatcher::monitor() {
6082 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006083 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006084 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006085 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006086}
6087
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006088/**
6089 * Wake up the dispatcher and wait until it processes all events and commands.
6090 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6091 * this method can be safely called from any thread, as long as you've ensured that
6092 * the work you are interested in completing has already been queued.
6093 */
6094bool InputDispatcher::waitForIdle() {
6095 /**
6096 * Timeout should represent the longest possible time that a device might spend processing
6097 * events and commands.
6098 */
6099 constexpr std::chrono::duration TIMEOUT = 100ms;
6100 std::unique_lock lock(mLock);
6101 mLooper->wake();
6102 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6103 return result == std::cv_status::no_timeout;
6104}
6105
Vishnu Naire798b472020-07-23 13:52:21 -07006106/**
6107 * Sets focus to the window identified by the token. This must be called
6108 * after updating any input window handles.
6109 *
6110 * Params:
6111 * request.token - input channel token used to identify the window that should gain focus.
6112 * request.focusedToken - the token that the caller expects currently to be focused. If the
6113 * specified token does not match the currently focused window, this request will be dropped.
6114 * If the specified focused token matches the currently focused window, the call will succeed.
6115 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6116 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6117 * when requesting the focus change. This determines which request gets
6118 * precedence if there is a focus change request from another source such as pointer down.
6119 */
Vishnu Nair958da932020-08-21 17:12:37 -07006120void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6121 { // acquire lock
6122 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006123 std::optional<FocusResolver::FocusChanges> changes =
6124 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6125 if (changes) {
6126 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006127 }
6128 } // release lock
6129 // Wake up poll loop since it may need to make new input dispatching choices.
6130 mLooper->wake();
6131}
6132
Vishnu Nairc519ff72021-01-21 08:23:08 -08006133void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6134 if (changes.oldFocus) {
6135 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006136 if (focusedInputChannel) {
6137 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6138 "focus left window");
6139 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006140 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006141 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006142 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006143 if (changes.newFocus) {
6144 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006145 }
6146
Prabir Pradhan99987712020-11-10 18:43:05 -08006147 // If a window has pointer capture, then it must have focus. We need to ensure that this
6148 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6149 // If the window loses focus before it loses pointer capture, then the window can be in a state
6150 // where it has pointer capture but not focus, violating the contract. Therefore we must
6151 // dispatch the pointer capture event before the focus event. Since focus events are added to
6152 // the front of the queue (above), we add the pointer capture event to the front of the queue
6153 // after the focus events are added. This ensures the pointer capture event ends up at the
6154 // front.
6155 disablePointerCaptureForcedLocked();
6156
Vishnu Nairc519ff72021-01-21 08:23:08 -08006157 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006158 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006159 }
6160}
Vishnu Nair958da932020-08-21 17:12:37 -07006161
Prabir Pradhan99987712020-11-10 18:43:05 -08006162void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006163 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006164 return;
6165 }
6166
6167 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6168
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006169 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006170 setPointerCaptureLocked(false);
6171 }
6172
6173 if (!mWindowTokenWithPointerCapture) {
6174 // No need to send capture changes because no window has capture.
6175 return;
6176 }
6177
6178 if (mPendingEvent != nullptr) {
6179 // Move the pending event to the front of the queue. This will give the chance
6180 // for the pending event to be dropped if it is a captured event.
6181 mInboundQueue.push_front(mPendingEvent);
6182 mPendingEvent = nullptr;
6183 }
6184
6185 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006186 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006187 mInboundQueue.push_front(std::move(entry));
6188}
6189
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006190void InputDispatcher::setPointerCaptureLocked(bool enable) {
6191 mCurrentPointerCaptureRequest.enable = enable;
6192 mCurrentPointerCaptureRequest.seq++;
6193 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006194 scoped_unlock unlock(mLock);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006195 mPolicy->setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006196 };
6197 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006198}
6199
Vishnu Nair599f1412021-06-21 10:39:58 -07006200void InputDispatcher::displayRemoved(int32_t displayId) {
6201 { // acquire lock
6202 std::scoped_lock _l(mLock);
6203 // Set an empty list to remove all handles from the specific display.
6204 setInputWindowsLocked(/* window handles */ {}, displayId);
6205 setFocusedApplicationLocked(displayId, nullptr);
6206 // Call focus resolver to clean up stale requests. This must be called after input windows
6207 // have been removed for the removed display.
6208 mFocusResolver.displayRemoved(displayId);
6209 } // release lock
6210
6211 // Wake up poll loop since it may need to make new input dispatching choices.
6212 mLooper->wake();
6213}
6214
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006215void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
6216 const std::vector<DisplayInfo>& displayInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006217 // The listener sends the windows as a flattened array. Separate the windows by display for
6218 // more convenient parsing.
6219 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
chaviw15fab6f2021-06-07 14:15:52 -05006220 for (const auto& info : windowInfos) {
6221 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
6222 handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
6223 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006224
6225 { // acquire lock
6226 std::scoped_lock _l(mLock);
6227 mDisplayInfos.clear();
6228 for (const auto& displayInfo : displayInfos) {
6229 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6230 }
6231
6232 for (const auto& [displayId, handles] : handlesPerDisplay) {
6233 setInputWindowsLocked(handles, displayId);
6234 }
6235 }
6236 // Wake up poll loop since it may need to make new input dispatching choices.
6237 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006238}
6239
Vishnu Nair062a8672021-09-03 16:07:44 -07006240bool InputDispatcher::shouldDropInput(
6241 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
6242 if (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT) ||
6243 (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT_IF_OBSCURED) &&
6244 isWindowObscuredLocked(windowHandle))) {
6245 ALOGW("Dropping %s event targeting %s as requested by input feature %s on display "
6246 "%" PRId32 ".",
6247 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
6248 windowHandle->getInfo()->inputFeatures.string().c_str(),
6249 windowHandle->getInfo()->displayId);
6250 return true;
6251 }
6252 return false;
6253}
6254
Garfield Tane84e6f92019-08-29 17:28:41 -07006255} // namespace android::inputdispatcher