blob: 6d5466a654e8d66c89c15984d470c7b3c3f27e1b [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
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
Garfield Tan15601662020-09-22 15:32:38 -070031// Log debug messages about channel creation
32#define DEBUG_CHANNEL_CREATION 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080033
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
Siarhei Vishniakou86587282019-09-09 18:20:15 +010038static constexpr bool DEBUG_FOCUS = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -080039
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +000040// Log debug messages about touch occlusion
41// STOPSHIP(b/169067926): Set to false
42static constexpr bool DEBUG_TOUCH_OCCLUSION = true;
43
Michael Wrightd02c5b62014-02-10 15:10:22 -080044// Log debug messages about the app switch latency optimization.
45#define DEBUG_APP_SWITCH 0
46
47// Log debug messages about hover events.
48#define DEBUG_HOVER 0
49
Michael Wright2b3c3302018-03-02 17:19:13 +000050#include <android-base/chrono_utils.h>
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080051#include <android-base/properties.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080052#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050053#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070054#include <binder/Binder.h>
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100055#include <binder/IServiceManager.h>
56#include <com/android/internal/compat/IPlatformCompatNative.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080057#include <input/InputDevice.h>
Michael Wright44753b12020-07-08 13:48:11 +010058#include <input/InputWindow.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070059#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000060#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070061#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010062#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070063#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080064
Michael Wright44753b12020-07-08 13:48:11 +010065#include <cerrno>
66#include <cinttypes>
67#include <climits>
68#include <cstddef>
69#include <ctime>
70#include <queue>
71#include <sstream>
72
73#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070074#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010075
Michael Wrightd02c5b62014-02-10 15:10:22 -080076#define INDENT " "
77#define INDENT2 " "
78#define INDENT3 " "
79#define INDENT4 " "
80
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080081using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000082using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080083using android::base::StringPrintf;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080084using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100085using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080086using android::os::InputEventInjectionResult;
87using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100088using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080089
Garfield Tane84e6f92019-08-29 17:28:41 -070090namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080091
92// Default input dispatching timeout if there is no focused application or paused window
93// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080094const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
95 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
96 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -080097
98// Amount of time to allow for all pending events to be processed when an app switch
99// key is on the way. This is used to preempt input dispatch and drop input events
100// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000101constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800102
103// Amount of time to allow for an event to be dispatched (measured since its eventTime)
104// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000105constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800106
Michael Wrightd02c5b62014-02-10 15:10:22 -0800107// 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 +0000108constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
109
110// Log a warning when an interception call takes longer than this to process.
111constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800112
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700113// Additional key latency in case a connection is still processing some motion events.
114// This will help with the case when a user touched a button that opens a new window,
115// and gives us the chance to dispatch the key to this new window.
116constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
117
Michael Wrightd02c5b62014-02-10 15:10:22 -0800118// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000119constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
120
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000121// Event log tags. See EventLogTags.logtags for reference
122constexpr int LOGTAG_INPUT_INTERACTION = 62000;
123constexpr int LOGTAG_INPUT_FOCUS = 62001;
124
Michael Wrightd02c5b62014-02-10 15:10:22 -0800125static inline nsecs_t now() {
126 return systemTime(SYSTEM_TIME_MONOTONIC);
127}
128
129static inline const char* toString(bool value) {
130 return value ? "true" : "false";
131}
132
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000133static inline const std::string toString(sp<IBinder> binder) {
134 if (binder == nullptr) {
135 return "<null>";
136 }
137 return StringPrintf("%p", binder.get());
138}
139
Michael Wrightd02c5b62014-02-10 15:10:22 -0800140static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700141 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
142 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800143}
144
145static bool isValidKeyAction(int32_t action) {
146 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700147 case AKEY_EVENT_ACTION_DOWN:
148 case AKEY_EVENT_ACTION_UP:
149 return true;
150 default:
151 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800152 }
153}
154
155static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700156 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800157 ALOGE("Key event has invalid action code 0x%x", action);
158 return false;
159 }
160 return true;
161}
162
Michael Wright7b159c92015-05-14 14:48:03 +0100163static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800164 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700165 case AMOTION_EVENT_ACTION_DOWN:
166 case AMOTION_EVENT_ACTION_UP:
167 case AMOTION_EVENT_ACTION_CANCEL:
168 case AMOTION_EVENT_ACTION_MOVE:
169 case AMOTION_EVENT_ACTION_OUTSIDE:
170 case AMOTION_EVENT_ACTION_HOVER_ENTER:
171 case AMOTION_EVENT_ACTION_HOVER_MOVE:
172 case AMOTION_EVENT_ACTION_HOVER_EXIT:
173 case AMOTION_EVENT_ACTION_SCROLL:
174 return true;
175 case AMOTION_EVENT_ACTION_POINTER_DOWN:
176 case AMOTION_EVENT_ACTION_POINTER_UP: {
177 int32_t index = getMotionEventActionPointerIndex(action);
178 return index >= 0 && index < pointerCount;
179 }
180 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
181 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
182 return actionButton != 0;
183 default:
184 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185 }
186}
187
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500188static int64_t millis(std::chrono::nanoseconds t) {
189 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
190}
191
Michael Wright7b159c92015-05-14 14:48:03 +0100192static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700193 const PointerProperties* pointerProperties) {
194 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800195 ALOGE("Motion event has invalid action code 0x%x", action);
196 return false;
197 }
198 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000199 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700200 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800201 return false;
202 }
203 BitSet32 pointerIdBits;
204 for (size_t i = 0; i < pointerCount; i++) {
205 int32_t id = pointerProperties[i].id;
206 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700207 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
208 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800209 return false;
210 }
211 if (pointerIdBits.hasBit(id)) {
212 ALOGE("Motion event has duplicate pointer id %d", id);
213 return false;
214 }
215 pointerIdBits.markBit(id);
216 }
217 return true;
218}
219
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000220static std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800221 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000222 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800223 }
224
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000225 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800226 bool first = true;
227 Region::const_iterator cur = region.begin();
228 Region::const_iterator const tail = region.end();
229 while (cur != tail) {
230 if (first) {
231 first = false;
232 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800233 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800234 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800235 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800236 cur++;
237 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000238 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800239}
240
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500241static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
242 constexpr size_t maxEntries = 50; // max events to print
243 constexpr size_t skipBegin = maxEntries / 2;
244 const size_t skipEnd = queue.size() - maxEntries / 2;
245 // skip from maxEntries / 2 ... size() - maxEntries/2
246 // only print from 0 .. skipBegin and then from skipEnd .. size()
247
248 std::string dump;
249 for (size_t i = 0; i < queue.size(); i++) {
250 const DispatchEntry& entry = *queue[i];
251 if (i >= skipBegin && i < skipEnd) {
252 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
253 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
254 continue;
255 }
256 dump.append(INDENT4);
257 dump += entry.eventEntry->getDescription();
258 dump += StringPrintf(", seq=%" PRIu32
259 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
260 entry.seq, entry.targetFlags, entry.resolvedAction,
261 ns2ms(currentTime - entry.eventEntry->eventTime));
262 if (entry.deliveryTime != 0) {
263 // This entry was delivered, so add information on how long we've been waiting
264 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
265 }
266 dump.append("\n");
267 }
268 return dump;
269}
270
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700271/**
272 * Find the entry in std::unordered_map by key, and return it.
273 * If the entry is not found, return a default constructed entry.
274 *
275 * Useful when the entries are vectors, since an empty vector will be returned
276 * if the entry is not found.
277 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
278 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700279template <typename K, typename V>
280static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700281 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700282 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800283}
284
chaviwaf87b3e2019-10-01 16:59:28 -0700285static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
286 if (first == second) {
287 return true;
288 }
289
290 if (first == nullptr || second == nullptr) {
291 return false;
292 }
293
294 return first->getToken() == second->getToken();
295}
296
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000297static bool haveSameApplicationToken(const InputWindowInfo* first, const InputWindowInfo* second) {
298 if (first == nullptr || second == nullptr) {
299 return false;
300 }
301 return first->applicationInfo.token != nullptr &&
302 first->applicationInfo.token == second->applicationInfo.token;
303}
304
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800305static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
306 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
307}
308
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000309static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700310 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000311 int32_t inputTargetFlags) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900312 if (eventEntry->type == EventEntry::Type::MOTION) {
313 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
Prabir Pradhanbd527712021-03-09 19:17:09 -0800314 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) == 0) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900315 const ui::Transform identityTransform;
Prabir Pradhanbd527712021-03-09 19:17:09 -0800316 // Use identity transform for events that are not pointer events because their axes
317 // values do not represent on-screen coordinates, so they should not have any window
318 // transformations applied to them.
yunho.shinf4a80b82020-11-16 21:13:57 +0900319 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700320 1.0f /*globalScaleFactor*/,
321 inputTarget.displaySize);
yunho.shinf4a80b82020-11-16 21:13:57 +0900322 }
323 }
324
chaviw1ff3d1e2020-07-01 15:53:47 -0700325 if (inputTarget.useDefaultPointerTransform()) {
326 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700327 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700328 inputTarget.globalScaleFactor,
329 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000330 }
331
332 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
333 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
334
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700335 std::vector<PointerCoords> pointerCoords;
336 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000337
338 // Use the first pointer information to normalize all other pointers. This could be any pointer
339 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700340 // uses the transform for the normalized pointer.
341 const ui::Transform& firstPointerTransform =
342 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
343 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000344
345 // Iterate through all pointers in the event to normalize against the first.
346 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
347 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
348 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700349 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000350
351 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700352 // First, apply the current pointer's transform to update the coordinates into
353 // window space.
354 pointerCoords[pointerIndex].transform(currTransform);
355 // Next, apply the inverse transform of the normalized coordinates so the
356 // current coordinates are transformed into the normalized coordinate space.
357 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000358 }
359
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700360 std::unique_ptr<MotionEntry> combinedMotionEntry =
361 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
362 motionEntry.deviceId, motionEntry.source,
363 motionEntry.displayId, motionEntry.policyFlags,
364 motionEntry.action, motionEntry.actionButton,
365 motionEntry.flags, motionEntry.metaState,
366 motionEntry.buttonState, motionEntry.classification,
367 motionEntry.edgeFlags, motionEntry.xPrecision,
368 motionEntry.yPrecision, motionEntry.xCursorPosition,
369 motionEntry.yCursorPosition, motionEntry.downTime,
370 motionEntry.pointerCount, motionEntry.pointerProperties,
371 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000372
373 if (motionEntry.injectionState) {
374 combinedMotionEntry->injectionState = motionEntry.injectionState;
375 combinedMotionEntry->injectionState->refCount += 1;
376 }
377
378 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700379 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Evan Rosky84f07f02021-04-16 10:42:42 -0700380 firstPointerTransform, inputTarget.globalScaleFactor,
381 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000382 return dispatchEntry;
383}
384
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700385static void addGestureMonitors(const std::vector<Monitor>& monitors,
386 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
387 float yOffset = 0) {
388 if (monitors.empty()) {
389 return;
390 }
391 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
392 for (const Monitor& monitor : monitors) {
393 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
394 }
395}
396
Garfield Tan15601662020-09-22 15:32:38 -0700397static status_t openInputChannelPair(const std::string& name,
398 std::shared_ptr<InputChannel>& serverChannel,
399 std::unique_ptr<InputChannel>& clientChannel) {
400 std::unique_ptr<InputChannel> uniqueServerChannel;
401 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
402
403 serverChannel = std::move(uniqueServerChannel);
404 return result;
405}
406
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500407template <typename T>
408static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
409 if (lhs == nullptr && rhs == nullptr) {
410 return true;
411 }
412 if (lhs == nullptr || rhs == nullptr) {
413 return false;
414 }
415 return *lhs == *rhs;
416}
417
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000418static sp<IPlatformCompatNative> getCompatService() {
419 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
420 if (service == nullptr) {
421 ALOGE("Failed to link to compat service");
422 return nullptr;
423 }
424 return interface_cast<IPlatformCompatNative>(service);
425}
426
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000427static KeyEvent createKeyEvent(const KeyEntry& entry) {
428 KeyEvent event;
429 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
430 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
431 entry.repeatCount, entry.downTime, entry.eventTime);
432 return event;
433}
434
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000435static std::optional<int32_t> findMonitorPidByToken(
436 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
437 const sp<IBinder>& token) {
438 for (const auto& it : monitorsByDisplay) {
439 const std::vector<Monitor>& monitors = it.second;
440 for (const Monitor& monitor : monitors) {
441 if (monitor.inputChannel->getConnectionToken() == token) {
442 return monitor.pid;
443 }
444 }
445 }
446 return std::nullopt;
447}
448
Michael Wrightd02c5b62014-02-10 15:10:22 -0800449// --- InputDispatcher ---
450
Garfield Tan00f511d2019-06-12 16:55:40 -0700451InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
452 : mPolicy(policy),
453 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700454 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800455 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700456 mAppSwitchSawKeyDown(false),
457 mAppSwitchDueTime(LONG_LONG_MAX),
458 mNextUnblockedEvent(nullptr),
459 mDispatchEnabled(false),
460 mDispatchFrozen(false),
461 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800462 // mInTouchMode will be initialized by the WindowManager to the default device config.
463 // To avoid leaking stack in case that call never comes, and for tests,
464 // initialize it here anyways.
465 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100466 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000467 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800468 mFocusedWindowRequestedPointerCapture(false),
469 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000470 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800471 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800472 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800473
Yi Kong9b14ac62018-07-17 13:48:38 -0700474 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800475
476 policy->getDispatcherConfiguration(&mConfig);
477}
478
479InputDispatcher::~InputDispatcher() {
480 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800481 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800482
483 resetKeyRepeatLocked();
484 releasePendingEventLocked();
485 drainInboundQueueLocked();
486 }
487
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000488 while (!mConnectionsByToken.empty()) {
489 sp<Connection> connection = mConnectionsByToken.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700490 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800491 }
492}
493
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700494status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700495 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700496 return ALREADY_EXISTS;
497 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700498 mThread = std::make_unique<InputThread>(
499 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
500 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700501}
502
503status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700504 if (mThread && mThread->isCallingThread()) {
505 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700506 return INVALID_OPERATION;
507 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700508 mThread.reset();
509 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700510}
511
Michael Wrightd02c5b62014-02-10 15:10:22 -0800512void InputDispatcher::dispatchOnce() {
513 nsecs_t nextWakeupTime = LONG_LONG_MAX;
514 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800515 std::scoped_lock _l(mLock);
516 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800517
518 // Run a dispatch loop if there are no pending commands.
519 // The dispatch loop might enqueue commands to run afterwards.
520 if (!haveCommandsLocked()) {
521 dispatchOnceInnerLocked(&nextWakeupTime);
522 }
523
524 // Run all pending commands if there are any.
525 // If any commands were run then force the next poll to wake up immediately.
526 if (runCommandsLockedInterruptible()) {
527 nextWakeupTime = LONG_LONG_MIN;
528 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800529
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700530 // If we are still waiting for ack on some events,
531 // we might have to wake up earlier to check if an app is anr'ing.
532 const nsecs_t nextAnrCheck = processAnrsLocked();
533 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
534
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800535 // We are about to enter an infinitely long sleep, because we have no commands or
536 // pending or queued events
537 if (nextWakeupTime == LONG_LONG_MAX) {
538 mDispatcherEnteredIdle.notify_all();
539 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800540 } // release lock
541
542 // Wait for callback or timeout or wake. (make sure we round up, not down)
543 nsecs_t currentTime = now();
544 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
545 mLooper->pollOnce(timeoutMillis);
546}
547
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700548/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500549 * Raise ANR if there is no focused window.
550 * Before the ANR is raised, do a final state check:
551 * 1. The currently focused application must be the same one we are waiting for.
552 * 2. Ensure we still don't have a focused window.
553 */
554void InputDispatcher::processNoFocusedWindowAnrLocked() {
555 // Check if the application that we are waiting for is still focused.
556 std::shared_ptr<InputApplicationHandle> focusedApplication =
557 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
558 if (focusedApplication == nullptr ||
559 focusedApplication->getApplicationToken() !=
560 mAwaitedFocusedApplication->getApplicationToken()) {
561 // Unexpected because we should have reset the ANR timer when focused application changed
562 ALOGE("Waited for a focused window, but focused application has already changed to %s",
563 focusedApplication->getName().c_str());
564 return; // The focused application has changed.
565 }
566
567 const sp<InputWindowHandle>& focusedWindowHandle =
568 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
569 if (focusedWindowHandle != nullptr) {
570 return; // We now have a focused window. No need for ANR.
571 }
572 onAnrLocked(mAwaitedFocusedApplication);
573}
574
575/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700576 * Check if any of the connections' wait queues have events that are too old.
577 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
578 * Return the time at which we should wake up next.
579 */
580nsecs_t InputDispatcher::processAnrsLocked() {
581 const nsecs_t currentTime = now();
582 nsecs_t nextAnrCheck = LONG_LONG_MAX;
583 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
584 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
585 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500586 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700587 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500588 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700589 return LONG_LONG_MIN;
590 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500591 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700592 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
593 }
594 }
595
596 // Check if any connection ANRs are due
597 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
598 if (currentTime < nextAnrCheck) { // most likely scenario
599 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
600 }
601
602 // If we reached here, we have an unresponsive connection.
603 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
604 if (connection == nullptr) {
605 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
606 return nextAnrCheck;
607 }
608 connection->responsive = false;
609 // Stop waking up for this unresponsive connection
610 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000611 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700612 return LONG_LONG_MIN;
613}
614
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500615std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700616 sp<InputWindowHandle> window = getWindowHandleLocked(token);
617 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500618 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700619 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500620 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700621}
622
Michael Wrightd02c5b62014-02-10 15:10:22 -0800623void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
624 nsecs_t currentTime = now();
625
Jeff Browndc5992e2014-04-11 01:27:26 -0700626 // Reset the key repeat timer whenever normal dispatch is suspended while the
627 // device is in a non-interactive state. This is to ensure that we abort a key
628 // repeat if the device is just coming out of sleep.
629 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800630 resetKeyRepeatLocked();
631 }
632
633 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
634 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100635 if (DEBUG_FOCUS) {
636 ALOGD("Dispatch frozen. Waiting some more.");
637 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800638 return;
639 }
640
641 // Optimize latency of app switches.
642 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
643 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
644 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
645 if (mAppSwitchDueTime < *nextWakeupTime) {
646 *nextWakeupTime = mAppSwitchDueTime;
647 }
648
649 // Ready to start a new event.
650 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700651 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700652 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800653 if (isAppSwitchDue) {
654 // The inbound queue is empty so the app switch key we were waiting
655 // for will never arrive. Stop waiting for it.
656 resetPendingAppSwitchLocked(false);
657 isAppSwitchDue = false;
658 }
659
660 // Synthesize a key repeat if appropriate.
661 if (mKeyRepeatState.lastKeyEntry) {
662 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
663 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
664 } else {
665 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
666 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
667 }
668 }
669 }
670
671 // Nothing to do if there is no pending event.
672 if (!mPendingEvent) {
673 return;
674 }
675 } else {
676 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700677 mPendingEvent = mInboundQueue.front();
678 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800679 traceInboundQueueLengthLocked();
680 }
681
682 // Poke user activity for this event.
683 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700684 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800685 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800686 }
687
688 // Now we have an event to dispatch.
689 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700690 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800691 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700692 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800693 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700694 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800695 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700696 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800697 }
698
699 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700700 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800701 }
702
703 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700704 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700705 const ConfigurationChangedEntry& typedEntry =
706 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700707 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700708 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700709 break;
710 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800711
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700712 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700713 const DeviceResetEntry& typedEntry =
714 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700715 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700716 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700717 break;
718 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800719
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100720 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700721 std::shared_ptr<FocusEntry> typedEntry =
722 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100723 dispatchFocusLocked(currentTime, typedEntry);
724 done = true;
725 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
726 break;
727 }
728
Prabir Pradhan99987712020-11-10 18:43:05 -0800729 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
730 const auto typedEntry =
731 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
732 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
733 done = true;
734 break;
735 }
736
arthurhungb89ccb02020-12-30 16:19:01 +0800737 case EventEntry::Type::DRAG: {
738 std::shared_ptr<DragEntry> typedEntry =
739 std::static_pointer_cast<DragEntry>(mPendingEvent);
740 dispatchDragLocked(currentTime, typedEntry);
741 done = true;
742 break;
743 }
744
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700745 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700746 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700747 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700748 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700749 resetPendingAppSwitchLocked(true);
750 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700751 } else if (dropReason == DropReason::NOT_DROPPED) {
752 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700753 }
754 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700755 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700756 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700757 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700758 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
759 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700760 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700761 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700762 break;
763 }
764
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700765 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700766 std::shared_ptr<MotionEntry> motionEntry =
767 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700768 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
769 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800770 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700771 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700772 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700773 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700774 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
775 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700776 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700777 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700778 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800779 }
Chris Yef59a2f42020-10-16 12:55:26 -0700780
781 case EventEntry::Type::SENSOR: {
782 std::shared_ptr<SensorEntry> sensorEntry =
783 std::static_pointer_cast<SensorEntry>(mPendingEvent);
784 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
785 dropReason = DropReason::APP_SWITCH;
786 }
787 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
788 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
789 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
790 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
791 dropReason = DropReason::STALE;
792 }
793 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
794 done = true;
795 break;
796 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800797 }
798
799 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700800 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700801 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800802 }
Michael Wright3a981722015-06-10 15:26:13 +0100803 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800804
805 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700806 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800807 }
808}
809
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700810/**
811 * Return true if the events preceding this incoming motion event should be dropped
812 * Return false otherwise (the default behaviour)
813 */
814bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700815 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700816 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700817
818 // Optimize case where the current application is unresponsive and the user
819 // decides to touch a window in a different application.
820 // If the application takes too long to catch up then we drop all events preceding
821 // the touch into the other window.
822 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700823 int32_t displayId = motionEntry.displayId;
824 int32_t x = static_cast<int32_t>(
825 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
826 int32_t y = static_cast<int32_t>(
827 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
828 sp<InputWindowHandle> touchedWindowHandle =
829 findTouchedWindowAtLocked(displayId, x, y, nullptr);
830 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700831 touchedWindowHandle->getApplicationToken() !=
832 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700833 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700834 ALOGI("Pruning input queue because user touched a different application while waiting "
835 "for %s",
836 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700837 return true;
838 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700839
840 // Alternatively, maybe there's a gesture monitor that could handle this event
841 std::vector<TouchedMonitor> gestureMonitors =
842 findTouchedGestureMonitorsLocked(displayId, {});
843 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
844 sp<Connection> connection =
845 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000846 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700847 // This monitor could take more input. Drop all events preceding this
848 // event, so that gesture monitor could get a chance to receive the stream
849 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
850 "responsive gesture monitor that may handle the event",
851 mAwaitedFocusedApplication->getName().c_str());
852 return true;
853 }
854 }
855 }
856
857 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
858 // yet been processed by some connections, the dispatcher will wait for these motion
859 // events to be processed before dispatching the key event. This is because these motion events
860 // may cause a new window to be launched, which the user might expect to receive focus.
861 // To prevent waiting forever for such events, just send the key to the currently focused window
862 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
863 ALOGD("Received a new pointer down event, stop waiting for events to process and "
864 "just send the pending key event to the focused window.");
865 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700866 }
867 return false;
868}
869
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700870bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700871 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700872 mInboundQueue.push_back(std::move(newEntry));
873 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800874 traceInboundQueueLengthLocked();
875
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700876 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700877 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700878 // Optimize app switch latency.
879 // If the application takes too long to catch up then we drop all events preceding
880 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700881 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700882 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700883 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700884 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700885 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700886 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800887#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700888 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800889#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700890 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700891 mAppSwitchSawKeyDown = false;
892 needWake = true;
893 }
894 }
895 }
896 break;
897 }
898
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700899 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700900 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
901 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700902 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800903 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700904 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800905 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100906 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700907 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
908 break;
909 }
910 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -0800911 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -0700912 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +0800913 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
914 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700915 // nothing to do
916 break;
917 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800918 }
919
920 return needWake;
921}
922
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700923void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -0700924 // Do not store sensor event in recent queue to avoid flooding the queue.
925 if (entry->type != EventEntry::Type::SENSOR) {
926 mRecentQueue.push_back(entry);
927 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700928 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700929 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800930 }
931}
932
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700933sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700934 int32_t y, TouchState* touchState,
935 bool addOutsideTargets,
arthurhungb89ccb02020-12-30 16:19:01 +0800936 bool addPortalWindows,
937 bool ignoreDragWindow) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700938 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
939 LOG_ALWAYS_FATAL(
940 "Must provide a valid touch state if adding portal windows or outside targets");
941 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800942 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700943 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800944 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +0800945 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +0800946 continue;
947 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800948 const InputWindowInfo* windowInfo = windowHandle->getInfo();
949 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100950 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800951
952 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100953 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
954 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
955 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800956 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800957 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700958 if (portalToDisplayId != ADISPLAY_ID_NONE &&
959 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800960 if (addPortalWindows) {
961 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700962 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800963 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700964 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700965 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800966 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800967 // Found window.
968 return windowHandle;
969 }
970 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800971
Michael Wright44753b12020-07-08 13:48:11 +0100972 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700973 touchState->addOrUpdateWindow(windowHandle,
974 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
975 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800976 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800977 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800978 }
979 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700980 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800981}
982
Garfield Tane84e6f92019-08-29 17:28:41 -0700983std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700984 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000985 std::vector<TouchedMonitor> touchedMonitors;
986
987 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
988 addGestureMonitors(monitors, touchedMonitors);
989 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
990 const InputWindowInfo* windowInfo = portalWindow->getInfo();
991 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700992 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
993 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000994 }
995 return touchedMonitors;
996}
997
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700998void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800999 const char* reason;
1000 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001001 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -08001002#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001003 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001004#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001005 reason = "inbound event was dropped because the policy consumed it";
1006 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001007 case DropReason::DISABLED:
1008 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001009 ALOGI("Dropped event because input dispatch is disabled.");
1010 }
1011 reason = "inbound event was dropped because input dispatch is disabled";
1012 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001013 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001014 ALOGI("Dropped event because of pending overdue app switch.");
1015 reason = "inbound event was dropped because of pending overdue app switch";
1016 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001017 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001018 ALOGI("Dropped event because the current application is not responding and the user "
1019 "has started interacting with a different application.");
1020 reason = "inbound event was dropped because the current application is not responding "
1021 "and the user has started interacting with a different application";
1022 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001023 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001024 ALOGI("Dropped event because it is stale.");
1025 reason = "inbound event was dropped because it is stale";
1026 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001027 case DropReason::NO_POINTER_CAPTURE:
1028 ALOGI("Dropped event because there is no window with Pointer Capture.");
1029 reason = "inbound event was dropped because there is no window with Pointer Capture";
1030 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001031 case DropReason::NOT_DROPPED: {
1032 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001033 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001034 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001035 }
1036
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001037 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001038 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001039 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1040 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001041 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001042 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001043 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001044 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1045 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001046 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1047 synthesizeCancelationEventsForAllConnectionsLocked(options);
1048 } else {
1049 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1050 synthesizeCancelationEventsForAllConnectionsLocked(options);
1051 }
1052 break;
1053 }
Chris Yef59a2f42020-10-16 12:55:26 -07001054 case EventEntry::Type::SENSOR: {
1055 break;
1056 }
arthurhungb89ccb02020-12-30 16:19:01 +08001057 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1058 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001059 break;
1060 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001061 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001062 case EventEntry::Type::CONFIGURATION_CHANGED:
1063 case EventEntry::Type::DEVICE_RESET: {
Chris Yef59a2f42020-10-16 12:55:26 -07001064 LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001065 break;
1066 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001067 }
1068}
1069
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001070static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001071 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1072 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001073}
1074
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001075bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1076 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1077 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1078 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001079}
1080
1081bool InputDispatcher::isAppSwitchPendingLocked() {
1082 return mAppSwitchDueTime != LONG_LONG_MAX;
1083}
1084
1085void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1086 mAppSwitchDueTime = LONG_LONG_MAX;
1087
1088#if DEBUG_APP_SWITCH
1089 if (handled) {
1090 ALOGD("App switch has arrived.");
1091 } else {
1092 ALOGD("App switch was abandoned.");
1093 }
1094#endif
1095}
1096
Michael Wrightd02c5b62014-02-10 15:10:22 -08001097bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001098 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001099}
1100
1101bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001102 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001103 return false;
1104 }
1105
1106 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001107 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001108 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001109 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001110 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001111
1112 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001113 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001114 return true;
1115}
1116
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001117void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1118 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001119}
1120
1121void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001122 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001123 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001124 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001125 releaseInboundEventLocked(entry);
1126 }
1127 traceInboundQueueLengthLocked();
1128}
1129
1130void InputDispatcher::releasePendingEventLocked() {
1131 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001132 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001133 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001134 }
1135}
1136
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001137void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001138 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001139 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001140#if DEBUG_DISPATCH_CYCLE
1141 ALOGD("Injected inbound event was dropped.");
1142#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001143 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001144 }
1145 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001146 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001147 }
1148 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001149}
1150
1151void InputDispatcher::resetKeyRepeatLocked() {
1152 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001153 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001154 }
1155}
1156
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001157std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1158 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001159
Michael Wright2e732952014-09-24 13:26:59 -07001160 uint32_t policyFlags = entry->policyFlags &
1161 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001162
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001163 std::shared_ptr<KeyEntry> newEntry =
1164 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1165 entry->source, entry->displayId, policyFlags, entry->action,
1166 entry->flags, entry->keyCode, entry->scanCode,
1167 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001168
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001169 newEntry->syntheticRepeat = true;
1170 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001171 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001172 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001173}
1174
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001175bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001176 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001177#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001178 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001179#endif
1180
1181 // Reset key repeating in case a keyboard device was added or removed or something.
1182 resetKeyRepeatLocked();
1183
1184 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001185 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1186 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001187 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001188 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001189 return true;
1190}
1191
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001192bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1193 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001194#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001195 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1196 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001197#endif
1198
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001199 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001200 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001201 synthesizeCancelationEventsForAllConnectionsLocked(options);
1202 return true;
1203}
1204
Vishnu Nairad321cd2020-08-20 16:40:21 -07001205void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001206 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001207 if (mPendingEvent != nullptr) {
1208 // Move the pending event to the front of the queue. This will give the chance
1209 // for the pending event to get dispatched to the newly focused window
1210 mInboundQueue.push_front(mPendingEvent);
1211 mPendingEvent = nullptr;
1212 }
1213
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001214 std::unique_ptr<FocusEntry> focusEntry =
1215 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1216 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001217
1218 // This event should go to the front of the queue, but behind all other focus events
1219 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001220 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001221 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001222 [](const std::shared_ptr<EventEntry>& event) {
1223 return event->type == EventEntry::Type::FOCUS;
1224 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001225
1226 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001227 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001228}
1229
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001230void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001231 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001232 if (channel == nullptr) {
1233 return; // Window has gone away
1234 }
1235 InputTarget target;
1236 target.inputChannel = channel;
1237 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1238 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001239 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1240 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001241 std::string reason = std::string("reason=").append(entry->reason);
1242 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001243 dispatchEventLocked(currentTime, entry, {target});
1244}
1245
Prabir Pradhan99987712020-11-10 18:43:05 -08001246void InputDispatcher::dispatchPointerCaptureChangedLocked(
1247 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1248 DropReason& dropReason) {
1249 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan167e6d92021-02-04 16:18:17 -08001250 if (entry->pointerCaptureEnabled && haveWindowWithPointerCapture) {
1251 LOG_ALWAYS_FATAL("Pointer Capture has already been enabled for the window.");
1252 }
1253 if (!entry->pointerCaptureEnabled && !haveWindowWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001254 // Pointer capture was already forcefully disabled because of focus change.
1255 dropReason = DropReason::NOT_DROPPED;
1256 return;
1257 }
1258
1259 // Set drop reason for early returns
1260 dropReason = DropReason::NO_POINTER_CAPTURE;
1261
1262 sp<IBinder> token;
1263 if (entry->pointerCaptureEnabled) {
1264 // Enable Pointer Capture
1265 if (!mFocusedWindowRequestedPointerCapture) {
1266 // This can happen if a window requests capture and immediately releases capture.
1267 ALOGW("No window requested Pointer Capture.");
1268 return;
1269 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08001270 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001271 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1272 mWindowTokenWithPointerCapture = token;
1273 } else {
1274 // Disable Pointer Capture
1275 token = mWindowTokenWithPointerCapture;
1276 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001277 if (mFocusedWindowRequestedPointerCapture) {
1278 mFocusedWindowRequestedPointerCapture = false;
1279 setPointerCaptureLocked(false);
1280 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001281 }
1282
1283 auto channel = getInputChannelLocked(token);
1284 if (channel == nullptr) {
1285 // Window has gone away, clean up Pointer Capture state.
1286 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001287 if (mFocusedWindowRequestedPointerCapture) {
1288 mFocusedWindowRequestedPointerCapture = false;
1289 setPointerCaptureLocked(false);
1290 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001291 return;
1292 }
1293 InputTarget target;
1294 target.inputChannel = channel;
1295 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1296 entry->dispatchInProgress = true;
1297 dispatchEventLocked(currentTime, entry, {target});
1298
1299 dropReason = DropReason::NOT_DROPPED;
1300}
1301
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001302bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001303 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001304 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001305 if (!entry->dispatchInProgress) {
1306 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1307 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1308 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1309 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001310 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001311 // We have seen two identical key downs in a row which indicates that the device
1312 // driver is automatically generating key repeats itself. We take note of the
1313 // repeat here, but we disable our own next key repeat timer since it is clear that
1314 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001315 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1316 // Make sure we don't get key down from a different device. If a different
1317 // device Id has same key pressed down, the new device Id will replace the
1318 // current one to hold the key repeat with repeat count reset.
1319 // In the future when got a KEY_UP on the device id, drop it and do not
1320 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001321 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1322 resetKeyRepeatLocked();
1323 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1324 } else {
1325 // Not a repeat. Save key down state in case we do see a repeat later.
1326 resetKeyRepeatLocked();
1327 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1328 }
1329 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001330 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1331 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001332 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001333#if DEBUG_INBOUND_EVENT_DETAILS
1334 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1335#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001336 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001337 resetKeyRepeatLocked();
1338 }
1339
1340 if (entry->repeatCount == 1) {
1341 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1342 } else {
1343 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1344 }
1345
1346 entry->dispatchInProgress = true;
1347
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001348 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001349 }
1350
1351 // Handle case where the policy asked us to try again later last time.
1352 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1353 if (currentTime < entry->interceptKeyWakeupTime) {
1354 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1355 *nextWakeupTime = entry->interceptKeyWakeupTime;
1356 }
1357 return false; // wait until next wakeup
1358 }
1359 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1360 entry->interceptKeyWakeupTime = 0;
1361 }
1362
1363 // Give the policy a chance to intercept the key.
1364 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1365 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001366 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001367 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001368 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001369 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001370 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001371 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001372 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001373 return false; // wait for the command to run
1374 } else {
1375 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1376 }
1377 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001378 if (*dropReason == DropReason::NOT_DROPPED) {
1379 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001380 }
1381 }
1382
1383 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001384 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001385 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001386 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1387 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001388 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001389 return true;
1390 }
1391
1392 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001393 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001394 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001395 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001396 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001397 return false;
1398 }
1399
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001400 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001401 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001402 return true;
1403 }
1404
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001405 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001406 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001407
1408 // Dispatch the key.
1409 dispatchEventLocked(currentTime, entry, inputTargets);
1410 return true;
1411}
1412
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001413void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001414#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001415 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001416 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1417 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001418 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1419 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1420 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001421#endif
1422}
1423
Chris Yef59a2f42020-10-16 12:55:26 -07001424void InputDispatcher::doNotifySensorLockedInterruptible(CommandEntry* commandEntry) {
1425 mLock.unlock();
1426
1427 const std::shared_ptr<SensorEntry>& entry = commandEntry->sensorEntry;
1428 if (entry->accuracyChanged) {
1429 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1430 }
1431 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1432 entry->hwTimestamp, entry->values);
1433 mLock.lock();
1434}
1435
1436void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, std::shared_ptr<SensorEntry> entry,
1437 DropReason* dropReason, nsecs_t* nextWakeupTime) {
1438#if DEBUG_OUTBOUND_EVENT_DETAILS
1439 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1440 "source=0x%x, sensorType=%s",
1441 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Prabir Pradhanbe05b5b2021-02-24 16:39:43 -08001442 NamedEnum::string(entry->sensorType).c_str());
Chris Yef59a2f42020-10-16 12:55:26 -07001443#endif
1444 std::unique_ptr<CommandEntry> commandEntry =
1445 std::make_unique<CommandEntry>(&InputDispatcher::doNotifySensorLockedInterruptible);
1446 commandEntry->sensorEntry = entry;
1447 postCommandLocked(std::move(commandEntry));
1448}
1449
1450bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
1451#if DEBUG_OUTBOUND_EVENT_DETAILS
1452 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
1453 NamedEnum::string(sensorType).c_str());
1454#endif
1455 { // acquire lock
1456 std::scoped_lock _l(mLock);
1457
1458 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1459 std::shared_ptr<EventEntry> entry = *it;
1460 if (entry->type == EventEntry::Type::SENSOR) {
1461 it = mInboundQueue.erase(it);
1462 releaseInboundEventLocked(entry);
1463 }
1464 }
1465 }
1466 return true;
1467}
1468
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001469bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001470 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001471 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001472 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001473 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001474 entry->dispatchInProgress = true;
1475
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001476 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001477 }
1478
1479 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001480 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001481 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001482 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1483 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001484 return true;
1485 }
1486
1487 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1488
1489 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001490 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001491
1492 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001493 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001494 if (isPointerEvent) {
1495 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001496 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001497 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001498 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001499 } else {
1500 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001501 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001502 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001503 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001504 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001505 return false;
1506 }
1507
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001508 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001509 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001510 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1511 return true;
1512 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001513 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001514 CancelationOptions::Mode mode(isPointerEvent
1515 ? CancelationOptions::CANCEL_POINTER_EVENTS
1516 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1517 CancelationOptions options(mode, "input event injection failed");
1518 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001519 return true;
1520 }
1521
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001522 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001523 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001524
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001525 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001526 std::unordered_map<int32_t, TouchState>::iterator it =
1527 mTouchStatesByDisplay.find(entry->displayId);
1528 if (it != mTouchStatesByDisplay.end()) {
1529 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001530 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001531 // The event has gone through these portal windows, so we add monitoring targets of
1532 // the corresponding displays as well.
1533 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001534 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001535 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001536 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001537 }
1538 }
1539 }
1540 }
1541
Michael Wrightd02c5b62014-02-10 15:10:22 -08001542 // Dispatch the motion.
1543 if (conflictingPointerActions) {
1544 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001545 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001546 synthesizeCancelationEventsForAllConnectionsLocked(options);
1547 }
1548 dispatchEventLocked(currentTime, entry, inputTargets);
1549 return true;
1550}
1551
arthurhungb89ccb02020-12-30 16:19:01 +08001552void InputDispatcher::enqueueDragEventLocked(const sp<InputWindowHandle>& windowHandle,
1553 bool isExiting, const MotionEntry& motionEntry) {
1554 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1555 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1556 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1557 PointerCoords pointerCoords;
1558 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1559 pointerCoords.transform(windowHandle->getInfo()->transform);
1560
1561 std::unique_ptr<DragEntry> dragEntry =
1562 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1563 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1564 pointerCoords.getY());
1565
1566 enqueueInboundEventLocked(std::move(dragEntry));
1567}
1568
1569void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1570 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1571 if (channel == nullptr) {
1572 return; // Window has gone away
1573 }
1574 InputTarget target;
1575 target.inputChannel = channel;
1576 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1577 entry->dispatchInProgress = true;
1578 dispatchEventLocked(currentTime, entry, {target});
1579}
1580
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001581void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001582#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001583 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001584 ", policyFlags=0x%x, "
1585 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1586 "metaState=0x%x, buttonState=0x%x,"
1587 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001588 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1589 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1590 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001591
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001592 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001593 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001594 "x=%f, y=%f, pressure=%f, size=%f, "
1595 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1596 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001597 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1598 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1599 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1600 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1601 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1602 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1603 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1604 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1605 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1606 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001607 }
1608#endif
1609}
1610
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001611void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1612 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001613 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001614 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001615#if DEBUG_DISPATCH_CYCLE
1616 ALOGD("dispatchEventToCurrentInputTargets");
1617#endif
1618
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001619 updateInteractionTokensLocked(*eventEntry, inputTargets);
1620
Michael Wrightd02c5b62014-02-10 15:10:22 -08001621 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1622
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001623 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001624
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001625 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001626 sp<Connection> connection =
1627 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001628 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001629 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001630 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001631 if (DEBUG_FOCUS) {
1632 ALOGD("Dropping event delivery to target with channel '%s' because it "
1633 "is no longer registered with the input dispatcher.",
1634 inputTarget.inputChannel->getName().c_str());
1635 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001636 }
1637 }
1638}
1639
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001640void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1641 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1642 // If the policy decides to close the app, we will get a channel removal event via
1643 // unregisterInputChannel, and will clean up the connection that way. We are already not
1644 // sending new pointers to the connection when it blocked, but focused events will continue to
1645 // pile up.
1646 ALOGW("Canceling events for %s because it is unresponsive",
1647 connection->inputChannel->getName().c_str());
1648 if (connection->status == Connection::STATUS_NORMAL) {
1649 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1650 "application not responding");
1651 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001652 }
1653}
1654
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001655void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001656 if (DEBUG_FOCUS) {
1657 ALOGD("Resetting ANR timeouts.");
1658 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001659
1660 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001661 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001662 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001663}
1664
Tiger Huang721e26f2018-07-24 22:26:19 +08001665/**
1666 * Get the display id that the given event should go to. If this event specifies a valid display id,
1667 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1668 * Focused display is the display that the user most recently interacted with.
1669 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001670int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001671 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001672 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001673 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001674 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1675 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001676 break;
1677 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001678 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001679 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1680 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001681 break;
1682 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001683 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001684 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001685 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001686 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001687 case EventEntry::Type::SENSOR:
1688 case EventEntry::Type::DRAG: {
Chris Yef59a2f42020-10-16 12:55:26 -07001689 ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001690 return ADISPLAY_ID_NONE;
1691 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001692 }
1693 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1694}
1695
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001696bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1697 const char* focusedWindowName) {
1698 if (mAnrTracker.empty()) {
1699 // already processed all events that we waited for
1700 mKeyIsWaitingForEventsTimeout = std::nullopt;
1701 return false;
1702 }
1703
1704 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1705 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001706 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001707 mKeyIsWaitingForEventsTimeout = currentTime +
1708 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1709 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001710 return true;
1711 }
1712
1713 // We still have pending events, and already started the timer
1714 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1715 return true; // Still waiting
1716 }
1717
1718 // Waited too long, and some connection still hasn't processed all motions
1719 // Just send the key to the focused window
1720 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1721 focusedWindowName);
1722 mKeyIsWaitingForEventsTimeout = std::nullopt;
1723 return false;
1724}
1725
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001726InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1727 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1728 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001729 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001730
Tiger Huang721e26f2018-07-24 22:26:19 +08001731 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001732 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001733 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001734 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1735
Michael Wrightd02c5b62014-02-10 15:10:22 -08001736 // If there is no currently focused window and no focused application
1737 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001738 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1739 ALOGI("Dropping %s event because there is no focused window or focused application in "
1740 "display %" PRId32 ".",
Chris Yef59a2f42020-10-16 12:55:26 -07001741 NamedEnum::string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001742 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001743 }
1744
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001745 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1746 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1747 // start interacting with another application via touch (app switch). This code can be removed
1748 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1749 // an app is expected to have a focused window.
1750 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1751 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1752 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001753 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1754 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1755 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001756 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001757 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001758 ALOGW("Waiting because no window has focus but %s may eventually add a "
1759 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001760 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001761 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001762 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001763 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1764 // Already raised ANR. Drop the event
1765 ALOGE("Dropping %s event because there is no focused window",
Chris Yef59a2f42020-10-16 12:55:26 -07001766 NamedEnum::string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001767 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001768 } else {
1769 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001770 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001771 }
1772 }
1773
1774 // we have a valid, non-null focused window
1775 resetNoFocusedWindowTimeoutLocked();
1776
Michael Wrightd02c5b62014-02-10 15:10:22 -08001777 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001778 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001779 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001780 }
1781
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001782 if (focusedWindowHandle->getInfo()->paused) {
1783 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001784 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001785 }
1786
1787 // If the event is a key event, then we must wait for all previous events to
1788 // complete before delivering it because previous events may have the
1789 // side-effect of transferring focus to a different window and we want to
1790 // ensure that the following keys are sent to the new window.
1791 //
1792 // Suppose the user touches a button in a window then immediately presses "A".
1793 // If the button causes a pop-up window to appear then we want to ensure that
1794 // the "A" key is delivered to the new pop-up window. This is because users
1795 // often anticipate pending UI changes when typing on a keyboard.
1796 // To obtain this behavior, we must serialize key events with respect to all
1797 // prior input events.
1798 if (entry.type == EventEntry::Type::KEY) {
1799 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1800 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001801 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001802 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001803 }
1804
1805 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001806 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001807 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1808 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001809
1810 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001811 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001812}
1813
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001814/**
1815 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1816 * that are currently unresponsive.
1817 */
1818std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1819 const std::vector<TouchedMonitor>& monitors) const {
1820 std::vector<TouchedMonitor> responsiveMonitors;
1821 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1822 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1823 sp<Connection> connection = getConnectionLocked(
1824 monitor.monitor.inputChannel->getConnectionToken());
1825 if (connection == nullptr) {
1826 ALOGE("Could not find connection for monitor %s",
1827 monitor.monitor.inputChannel->getName().c_str());
1828 return false;
1829 }
1830 if (!connection->responsive) {
1831 ALOGW("Unresponsive monitor %s will not get the new gesture",
1832 connection->inputChannel->getName().c_str());
1833 return false;
1834 }
1835 return true;
1836 });
1837 return responsiveMonitors;
1838}
1839
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001840InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1841 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1842 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001843 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001844 enum InjectionPermission {
1845 INJECTION_PERMISSION_UNKNOWN,
1846 INJECTION_PERMISSION_GRANTED,
1847 INJECTION_PERMISSION_DENIED
1848 };
1849
Michael Wrightd02c5b62014-02-10 15:10:22 -08001850 // For security reasons, we defer updating the touch state until we are sure that
1851 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001852 int32_t displayId = entry.displayId;
1853 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001854 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1855
1856 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001857 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001858 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001859 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1860 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001861
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001862 // Copy current touch state into tempTouchState.
1863 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1864 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001865 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001866 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001867 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1868 mTouchStatesByDisplay.find(displayId);
1869 if (oldStateIt != mTouchStatesByDisplay.end()) {
1870 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001871 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001872 }
1873
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001874 bool isSplit = tempTouchState.split;
1875 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1876 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1877 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001878 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1879 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1880 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1881 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1882 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001883 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001884 bool wrongDevice = false;
1885 if (newGesture) {
1886 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001887 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001888 ALOGI("Dropping event because a pointer for a different device is already down "
1889 "in display %" PRId32,
1890 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001891 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001892 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001893 switchedDevice = false;
1894 wrongDevice = true;
1895 goto Failed;
1896 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001897 tempTouchState.reset();
1898 tempTouchState.down = down;
1899 tempTouchState.deviceId = entry.deviceId;
1900 tempTouchState.source = entry.source;
1901 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001902 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001903 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001904 ALOGI("Dropping move event because a pointer for a different device is already active "
1905 "in display %" PRId32,
1906 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001907 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001908 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001909 switchedDevice = false;
1910 wrongDevice = true;
1911 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001912 }
1913
1914 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1915 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1916
Garfield Tan00f511d2019-06-12 16:55:40 -07001917 int32_t x;
1918 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001919 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001920 // Always dispatch mouse events to cursor position.
1921 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001922 x = int32_t(entry.xCursorPosition);
1923 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001924 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001925 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1926 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001927 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001928 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001929 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001930 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1931 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001932
1933 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001934 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001935 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001936
Michael Wrightd02c5b62014-02-10 15:10:22 -08001937 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001938 if (newTouchedWindowHandle != nullptr &&
1939 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001940 // New window supports splitting, but we should never split mouse events.
1941 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001942 } else if (isSplit) {
1943 // New window does not support splitting but we have already split events.
1944 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001945 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001946 }
1947
1948 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001949 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001950 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001951 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001952 }
1953
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001954 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1955 ALOGI("Not sending touch event to %s because it is paused",
1956 newTouchedWindowHandle->getName().c_str());
1957 newTouchedWindowHandle = nullptr;
1958 }
1959
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001960 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001961 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001962 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1963 if (!isResponsive) {
1964 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001965 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1966 newTouchedWindowHandle = nullptr;
1967 }
1968 }
1969
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001970 // Drop events that can't be trusted due to occlusion
1971 if (newTouchedWindowHandle != nullptr &&
1972 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1973 TouchOcclusionInfo occlusionInfo =
1974 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001975 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001976 if (DEBUG_TOUCH_OCCLUSION) {
1977 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1978 for (const auto& log : occlusionInfo.debugInfo) {
1979 ALOGD("%s", log.c_str());
1980 }
1981 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001982 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
1983 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1984 ALOGW("Dropping untrusted touch event due to %s/%d",
1985 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1986 newTouchedWindowHandle = nullptr;
1987 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001988 }
1989 }
1990
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001991 // Also don't send the new touch event to unresponsive gesture monitors
1992 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1993
Michael Wright3dd60e22019-03-27 22:06:44 +00001994 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1995 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001996 "(%d, %d) in display %" PRId32 ".",
1997 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001998 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001999 goto Failed;
2000 }
2001
2002 if (newTouchedWindowHandle != nullptr) {
2003 // Set target flags.
2004 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
2005 if (isSplit) {
2006 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002007 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002008 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2009 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2010 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2011 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2012 }
2013
2014 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07002015 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2016 newHoverWindowHandle = nullptr;
2017 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002018 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002019 }
2020
2021 // Update the temporary touch state.
2022 BitSet32 pointerIds;
2023 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002024 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002025 pointerIds.markBit(pointerId);
2026 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002027 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002028 }
2029
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002030 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002031 } else {
2032 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2033
2034 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002035 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002036 if (DEBUG_FOCUS) {
2037 ALOGD("Dropping event because the pointer is not down or we previously "
2038 "dropped the pointer down event in display %" PRId32,
2039 displayId);
2040 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002041 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002042 goto Failed;
2043 }
2044
arthurhung6d4bed92021-03-17 11:59:33 +08002045 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002046
Michael Wrightd02c5b62014-02-10 15:10:22 -08002047 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002048 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002049 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002050 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2051 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002052
2053 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002054 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002055 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002056 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2057 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002058 if (DEBUG_FOCUS) {
2059 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2060 oldTouchedWindowHandle->getName().c_str(),
2061 newTouchedWindowHandle->getName().c_str(), displayId);
2062 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002063 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002064 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2065 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2066 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067
2068 // Make a slippery entrance into the new window.
2069 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2070 isSplit = true;
2071 }
2072
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002073 int32_t targetFlags =
2074 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002075 if (isSplit) {
2076 targetFlags |= InputTarget::FLAG_SPLIT;
2077 }
2078 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2079 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002080 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2081 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002082 }
2083
2084 BitSet32 pointerIds;
2085 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002086 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002087 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002088 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002089 }
2090 }
2091 }
2092
2093 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002094 // Let the previous window know that the hover sequence is over, unless we already did it
2095 // when dispatching it as is to newTouchedWindowHandle.
2096 if (mLastHoverWindowHandle != nullptr &&
2097 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2098 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002099#if DEBUG_HOVER
2100 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002101 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002102#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002103 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2104 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002105 }
2106
Garfield Tandf26e862020-07-01 20:18:19 -07002107 // Let the new window know that the hover sequence is starting, unless we already did it
2108 // when dispatching it as is to newTouchedWindowHandle.
2109 if (newHoverWindowHandle != nullptr &&
2110 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2111 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002112#if DEBUG_HOVER
2113 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002114 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002115#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002116 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2117 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2118 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002119 }
2120 }
2121
2122 // Check permission to inject into all touched foreground windows and ensure there
2123 // is at least one touched foreground window.
2124 {
2125 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002126 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002127 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2128 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002129 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002130 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002131 injectionPermission = INJECTION_PERMISSION_DENIED;
2132 goto Failed;
2133 }
2134 }
2135 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002136 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002137 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002138 ALOGI("Dropping event because there is no touched foreground window in display "
2139 "%" PRId32 " or gesture monitor to receive it.",
2140 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002141 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002142 goto Failed;
2143 }
2144
2145 // Permission granted to injection into all touched foreground windows.
2146 injectionPermission = INJECTION_PERMISSION_GRANTED;
2147 }
2148
2149 // Check whether windows listening for outside touches are owned by the same UID. If it is
2150 // set the policy flag that we will not reveal coordinate information to this window.
2151 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2152 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002153 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002154 if (foregroundWindowHandle) {
2155 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002156 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002157 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2158 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
2159 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002160 tempTouchState.addOrUpdateWindow(inputWindowHandle,
2161 InputTarget::FLAG_ZERO_COORDS,
2162 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002163 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002164 }
2165 }
2166 }
2167 }
2168
Michael Wrightd02c5b62014-02-10 15:10:22 -08002169 // If this is the first pointer going down and the touched window has a wallpaper
2170 // then also add the touched wallpaper windows so they are locked in for the duration
2171 // of the touch gesture.
2172 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2173 // engine only supports touch events. We would need to add a mechanism similar
2174 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2175 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2176 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002177 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002178 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07002179 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002180 getWindowHandlesLocked(displayId);
2181 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002182 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002183 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01002184 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002185 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002186 .addOrUpdateWindow(windowHandle,
2187 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2188 InputTarget::
2189 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2190 InputTarget::FLAG_DISPATCH_AS_IS,
2191 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002192 }
2193 }
2194 }
2195 }
2196
2197 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002198 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002199
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002200 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002201 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002202 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002203 }
2204
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002205 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002206 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002207 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002208 }
2209
Michael Wrightd02c5b62014-02-10 15:10:22 -08002210 // Drop the outside or hover touch windows since we will not care about them
2211 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002212 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002213
2214Failed:
2215 // Check injection permission once and for all.
2216 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002217 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002218 injectionPermission = INJECTION_PERMISSION_GRANTED;
2219 } else {
2220 injectionPermission = INJECTION_PERMISSION_DENIED;
2221 }
2222 }
2223
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002224 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2225 return injectionResult;
2226 }
2227
Michael Wrightd02c5b62014-02-10 15:10:22 -08002228 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002229 if (!wrongDevice) {
2230 if (switchedDevice) {
2231 if (DEBUG_FOCUS) {
2232 ALOGD("Conflicting pointer actions: Switched to a different device.");
2233 }
2234 *outConflictingPointerActions = true;
2235 }
2236
2237 if (isHoverAction) {
2238 // Started hovering, therefore no longer down.
2239 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002240 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002241 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2242 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002243 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002244 *outConflictingPointerActions = true;
2245 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002246 tempTouchState.reset();
2247 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2248 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2249 tempTouchState.deviceId = entry.deviceId;
2250 tempTouchState.source = entry.source;
2251 tempTouchState.displayId = displayId;
2252 }
2253 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2254 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2255 // All pointers up or canceled.
2256 tempTouchState.reset();
2257 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2258 // First pointer went down.
2259 if (oldState && oldState->down) {
2260 if (DEBUG_FOCUS) {
2261 ALOGD("Conflicting pointer actions: Down received while already down.");
2262 }
2263 *outConflictingPointerActions = true;
2264 }
2265 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2266 // One pointer went up.
2267 if (isSplit) {
2268 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2269 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002270
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002271 for (size_t i = 0; i < tempTouchState.windows.size();) {
2272 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2273 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2274 touchedWindow.pointerIds.clearBit(pointerId);
2275 if (touchedWindow.pointerIds.isEmpty()) {
2276 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2277 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002278 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002279 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002280 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002281 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002282 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002283 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002284
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002285 // Save changes unless the action was scroll in which case the temporary touch
2286 // state was only valid for this one action.
2287 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2288 if (tempTouchState.displayId >= 0) {
2289 mTouchStatesByDisplay[displayId] = tempTouchState;
2290 } else {
2291 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002292 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002293 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002294
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002295 // Update hover state.
2296 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002297 }
2298
Michael Wrightd02c5b62014-02-10 15:10:22 -08002299 return injectionResult;
2300}
2301
arthurhung6d4bed92021-03-17 11:59:33 +08002302void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
2303 const sp<InputWindowHandle> dropWindow =
2304 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
2305 false /*addOutsideTargets*/, false /*addPortalWindows*/,
2306 true /*ignoreDragWindow*/);
2307 if (dropWindow) {
2308 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
2309 notifyDropWindowLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002310 } else {
2311 notifyDropWindowLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002312 }
2313 mDragState.reset();
2314}
2315
2316void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2317 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002318 return;
2319 }
2320
arthurhung6d4bed92021-03-17 11:59:33 +08002321 if (!mDragState->isStartDrag) {
2322 mDragState->isStartDrag = true;
2323 mDragState->isStylusButtonDownAtStart =
2324 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2325 }
2326
arthurhungb89ccb02020-12-30 16:19:01 +08002327 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2328 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2329 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2330 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002331 // Handle the special case : stylus button no longer pressed.
2332 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2333 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2334 finishDragAndDrop(entry.displayId, x, y);
2335 return;
2336 }
2337
arthurhungb89ccb02020-12-30 16:19:01 +08002338 const sp<InputWindowHandle> hoverWindowHandle =
arthurhung6d4bed92021-03-17 11:59:33 +08002339 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
arthurhungb89ccb02020-12-30 16:19:01 +08002340 false /*addOutsideTargets*/, false /*addPortalWindows*/,
2341 true /*ignoreDragWindow*/);
2342 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002343 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2344 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2345 if (mDragState->dragHoverWindowHandle != nullptr) {
2346 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2347 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002348 }
arthurhung6d4bed92021-03-17 11:59:33 +08002349 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002350 }
2351 // enqueue drag location if needed.
2352 if (hoverWindowHandle != nullptr) {
2353 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2354 }
arthurhung6d4bed92021-03-17 11:59:33 +08002355 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2356 finishDragAndDrop(entry.displayId, x, y);
2357 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Arthur Hung6d0571e2021-04-09 20:18:16 +08002358 notifyDropWindowLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002359 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002360 }
2361}
2362
Michael Wrightd02c5b62014-02-10 15:10:22 -08002363void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002364 int32_t targetFlags, BitSet32 pointerIds,
2365 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002366 std::vector<InputTarget>::iterator it =
2367 std::find_if(inputTargets.begin(), inputTargets.end(),
2368 [&windowHandle](const InputTarget& inputTarget) {
2369 return inputTarget.inputChannel->getConnectionToken() ==
2370 windowHandle->getToken();
2371 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002372
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002373 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002374
2375 if (it == inputTargets.end()) {
2376 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002377 std::shared_ptr<InputChannel> inputChannel =
2378 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002379 if (inputChannel == nullptr) {
2380 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2381 return;
2382 }
2383 inputTarget.inputChannel = inputChannel;
2384 inputTarget.flags = targetFlags;
2385 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Evan Rosky84f07f02021-04-16 10:42:42 -07002386 inputTarget.displaySize =
2387 vec2(windowHandle->getInfo()->displayWidth, windowHandle->getInfo()->displayHeight);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002388 inputTargets.push_back(inputTarget);
2389 it = inputTargets.end() - 1;
2390 }
2391
2392 ALOG_ASSERT(it->flags == targetFlags);
2393 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2394
chaviw1ff3d1e2020-07-01 15:53:47 -07002395 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002396}
2397
Michael Wright3dd60e22019-03-27 22:06:44 +00002398void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002399 int32_t displayId, float xOffset,
2400 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002401 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2402 mGlobalMonitorsByDisplay.find(displayId);
2403
2404 if (it != mGlobalMonitorsByDisplay.end()) {
2405 const std::vector<Monitor>& monitors = it->second;
2406 for (const Monitor& monitor : monitors) {
2407 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002408 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002409 }
2410}
2411
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002412void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2413 float yOffset,
2414 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002415 InputTarget target;
2416 target.inputChannel = monitor.inputChannel;
2417 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002418 ui::Transform t;
2419 t.set(xOffset, yOffset);
2420 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002421 inputTargets.push_back(target);
2422}
2423
Michael Wrightd02c5b62014-02-10 15:10:22 -08002424bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002425 const InjectionState* injectionState) {
2426 if (injectionState &&
2427 (windowHandle == nullptr ||
2428 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2429 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002430 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002431 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002432 "owned by uid %d",
2433 injectionState->injectorPid, injectionState->injectorUid,
2434 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002435 } else {
2436 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002437 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002438 }
2439 return false;
2440 }
2441 return true;
2442}
2443
Robert Carrc9bf1d32020-04-13 17:21:08 -07002444/**
2445 * Indicate whether one window handle should be considered as obscuring
2446 * another window handle. We only check a few preconditions. Actually
2447 * checking the bounds is left to the caller.
2448 */
2449static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2450 const sp<InputWindowHandle>& otherHandle) {
2451 // Compare by token so cloned layers aren't counted
2452 if (haveSameToken(windowHandle, otherHandle)) {
2453 return false;
2454 }
2455 auto info = windowHandle->getInfo();
2456 auto otherInfo = otherHandle->getInfo();
2457 if (!otherInfo->visible) {
2458 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002459 } else if (otherInfo->alpha == 0 &&
2460 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2461 // Those act as if they were invisible, so we don't need to flag them.
2462 // We do want to potentially flag touchable windows even if they have 0
2463 // opacity, since they can consume touches and alter the effects of the
2464 // user interaction (eg. apps that rely on
2465 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2466 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2467 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002468 } else if (info->ownerUid == otherInfo->ownerUid) {
2469 // If ownerUid is the same we don't generate occlusion events as there
2470 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002471 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002472 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002473 return false;
2474 } else if (otherInfo->displayId != info->displayId) {
2475 return false;
2476 }
2477 return true;
2478}
2479
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002480/**
2481 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2482 * untrusted, one should check:
2483 *
2484 * 1. If result.hasBlockingOcclusion is true.
2485 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2486 * BLOCK_UNTRUSTED.
2487 *
2488 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2489 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2490 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2491 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2492 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2493 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2494 *
2495 * If neither of those is true, then it means the touch can be allowed.
2496 */
2497InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2498 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002499 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2500 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002501 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2502 TouchOcclusionInfo info;
2503 info.hasBlockingOcclusion = false;
2504 info.obscuringOpacity = 0;
2505 info.obscuringUid = -1;
2506 std::map<int32_t, float> opacityByUid;
2507 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2508 if (windowHandle == otherHandle) {
2509 break; // All future windows are below us. Exit early.
2510 }
2511 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002512 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2513 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002514 if (DEBUG_TOUCH_OCCLUSION) {
2515 info.debugInfo.push_back(
2516 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2517 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002518 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2519 // we perform the checks below to see if the touch can be propagated or not based on the
2520 // window's touch occlusion mode
2521 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2522 info.hasBlockingOcclusion = true;
2523 info.obscuringUid = otherInfo->ownerUid;
2524 info.obscuringPackage = otherInfo->packageName;
2525 break;
2526 }
2527 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2528 uint32_t uid = otherInfo->ownerUid;
2529 float opacity =
2530 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2531 // Given windows A and B:
2532 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2533 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2534 opacityByUid[uid] = opacity;
2535 if (opacity > info.obscuringOpacity) {
2536 info.obscuringOpacity = opacity;
2537 info.obscuringUid = uid;
2538 info.obscuringPackage = otherInfo->packageName;
2539 }
2540 }
2541 }
2542 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002543 if (DEBUG_TOUCH_OCCLUSION) {
2544 info.debugInfo.push_back(
2545 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2546 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002547 return info;
2548}
2549
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002550std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2551 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002552 return StringPrintf(INDENT2
2553 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2554 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2555 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2556 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002557 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002558 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002559 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002560 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2561 info->frameTop, info->frameRight, info->frameBottom,
2562 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002563 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2564 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2565 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002566}
2567
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002568bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2569 if (occlusionInfo.hasBlockingOcclusion) {
2570 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2571 occlusionInfo.obscuringUid);
2572 return false;
2573 }
2574 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2575 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2576 "%.2f, maximum allowed = %.2f)",
2577 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2578 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2579 return false;
2580 }
2581 return true;
2582}
2583
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002584bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2585 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002586 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002587 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002588 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002589 if (windowHandle == otherHandle) {
2590 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002591 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002592 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002593 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002594 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002595 return true;
2596 }
2597 }
2598 return false;
2599}
2600
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002601bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2602 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002603 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002604 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002605 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002606 if (windowHandle == otherHandle) {
2607 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002608 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002609 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002610 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002611 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002612 return true;
2613 }
2614 }
2615 return false;
2616}
2617
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002618std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002619 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002620 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002621 if (applicationHandle != nullptr) {
2622 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002623 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002624 } else {
2625 return applicationHandle->getName();
2626 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002627 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002628 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002629 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002630 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002631 }
2632}
2633
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002634void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002635 if (eventEntry.type == EventEntry::Type::FOCUS ||
arthurhungb89ccb02020-12-30 16:19:01 +08002636 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED ||
2637 eventEntry.type == EventEntry::Type::DRAG) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002638 // Focus or pointer capture changed events are passed to apps, but do not represent user
2639 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002640 return;
2641 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002642 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002643 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002644 if (focusedWindowHandle != nullptr) {
2645 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002646 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002647#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002648 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002649#endif
2650 return;
2651 }
2652 }
2653
2654 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002655 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002656 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002657 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2658 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002659 return;
2660 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002661
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002662 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002663 eventType = USER_ACTIVITY_EVENT_TOUCH;
2664 }
2665 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002666 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002667 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002668 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2669 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002670 return;
2671 }
2672 eventType = USER_ACTIVITY_EVENT_BUTTON;
2673 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002674 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002675 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002676 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002677 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002678 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08002679 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2680 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002681 LOG_ALWAYS_FATAL("%s events are not user activity",
Chris Yef59a2f42020-10-16 12:55:26 -07002682 NamedEnum::string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002683 break;
2684 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002685 }
2686
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002687 std::unique_ptr<CommandEntry> commandEntry =
2688 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002689 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002690 commandEntry->userActivityEventType = eventType;
Sean Stoutb4e0a592021-02-23 07:34:53 -08002691 commandEntry->displayId = displayId;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002692 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002693}
2694
2695void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002696 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002697 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002698 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002699 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002700 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002701 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002702 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002703 ATRACE_NAME(message.c_str());
2704 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002705#if DEBUG_DISPATCH_CYCLE
2706 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002707 "globalScaleFactor=%f, pointerIds=0x%x %s",
2708 connection->getInputChannelName().c_str(), inputTarget.flags,
2709 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2710 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002711#endif
2712
2713 // Skip this event if the connection status is not normal.
2714 // We don't want to enqueue additional outbound events if the connection is broken.
2715 if (connection->status != Connection::STATUS_NORMAL) {
2716#if DEBUG_DISPATCH_CYCLE
2717 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002718 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002719#endif
2720 return;
2721 }
2722
2723 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002724 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2725 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2726 "Entry type %s should not have FLAG_SPLIT",
Chris Yef59a2f42020-10-16 12:55:26 -07002727 NamedEnum::string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002728
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002729 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002730 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002731 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002732 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002733 if (!splitMotionEntry) {
2734 return; // split event was dropped
2735 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002736 if (DEBUG_FOCUS) {
2737 ALOGD("channel '%s' ~ Split motion event.",
2738 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002739 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002740 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002741 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2742 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002743 return;
2744 }
2745 }
2746
2747 // Not splitting. Enqueue dispatch entries for the event as is.
2748 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2749}
2750
2751void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002752 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002753 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002754 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002755 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002756 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002757 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002758 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002759 ATRACE_NAME(message.c_str());
2760 }
2761
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002762 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002763
2764 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002765 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002766 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002767 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002768 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002769 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002770 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002771 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002772 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002773 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002774 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002775 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002776 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002777
2778 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002779 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002780 startDispatchCycleLocked(currentTime, connection);
2781 }
2782}
2783
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002784void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002785 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002786 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002787 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002788 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002789 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2790 connection->getInputChannelName().c_str(),
2791 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002792 ATRACE_NAME(message.c_str());
2793 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002794 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002795 if (!(inputTargetFlags & dispatchMode)) {
2796 return;
2797 }
2798 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2799
2800 // This is a new event.
2801 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002802 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002803 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002804
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002805 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2806 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002807 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002808 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002809 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002810 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002811 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002812 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002813 dispatchEntry->resolvedAction = keyEntry.action;
2814 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002815
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002816 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2817 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002818#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002819 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2820 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002821#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002822 return; // skip the inconsistent event
2823 }
2824 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002825 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002826
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002827 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002828 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002829 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2830 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2831 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2832 static_cast<int32_t>(IdGenerator::Source::OTHER);
2833 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002834 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2835 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2836 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2837 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2838 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2839 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2840 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2841 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2842 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2843 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2844 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002845 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002846 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002847 }
2848 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002849 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2850 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002851#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002852 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2853 "event",
2854 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002855#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002856 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2857 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002858
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002859 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002860 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2861 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2862 }
2863 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2864 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2865 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002866
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002867 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2868 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002869#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002870 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2871 "event",
2872 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002873#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002874 return; // skip the inconsistent event
2875 }
2876
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002877 dispatchEntry->resolvedEventId =
2878 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2879 ? mIdGenerator.nextId()
2880 : motionEntry.id;
2881 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2882 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2883 ") to MotionEvent(id=0x%" PRIx32 ").",
2884 motionEntry.id, dispatchEntry->resolvedEventId);
2885 ATRACE_NAME(message.c_str());
2886 }
2887
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08002888 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
2889 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
2890 // Skip reporting pointer down outside focus to the policy.
2891 break;
2892 }
2893
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002894 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002895 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002896
2897 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002898 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002899 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08002900 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2901 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002902 break;
2903 }
Chris Yef59a2f42020-10-16 12:55:26 -07002904 case EventEntry::Type::SENSOR: {
2905 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
2906 break;
2907 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002908 case EventEntry::Type::CONFIGURATION_CHANGED:
2909 case EventEntry::Type::DEVICE_RESET: {
2910 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chris Yef59a2f42020-10-16 12:55:26 -07002911 NamedEnum::string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002912 break;
2913 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002914 }
2915
2916 // Remember that we are waiting for this dispatch to complete.
2917 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002918 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002919 }
2920
2921 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002922 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00002923 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07002924}
2925
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002926/**
2927 * This function is purely for debugging. It helps us understand where the user interaction
2928 * was taking place. For example, if user is touching launcher, we will see a log that user
2929 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2930 * We will see both launcher and wallpaper in that list.
2931 * Once the interaction with a particular set of connections starts, no new logs will be printed
2932 * until the set of interacted connections changes.
2933 *
2934 * The following items are skipped, to reduce the logspam:
2935 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2936 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2937 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2938 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2939 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002940 */
2941void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2942 const std::vector<InputTarget>& targets) {
2943 // Skip ACTION_UP events, and all events other than keys and motions
2944 if (entry.type == EventEntry::Type::KEY) {
2945 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2946 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2947 return;
2948 }
2949 } else if (entry.type == EventEntry::Type::MOTION) {
2950 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2951 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2952 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2953 return;
2954 }
2955 } else {
2956 return; // Not a key or a motion
2957 }
2958
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07002959 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002960 std::vector<sp<Connection>> newConnections;
2961 for (const InputTarget& target : targets) {
2962 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2963 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2964 continue; // Skip windows that receive ACTION_OUTSIDE
2965 }
2966
2967 sp<IBinder> token = target.inputChannel->getConnectionToken();
2968 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002969 if (connection == nullptr) {
2970 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002971 }
2972 newConnectionTokens.insert(std::move(token));
2973 newConnections.emplace_back(connection);
2974 }
2975 if (newConnectionTokens == mInteractionConnectionTokens) {
2976 return; // no change
2977 }
2978 mInteractionConnectionTokens = newConnectionTokens;
2979
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002980 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002981 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002982 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002983 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002984 std::string message = "Interaction with: " + targetList;
2985 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002986 message += "<none>";
2987 }
2988 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2989}
2990
chaviwfd6d3512019-03-25 13:23:49 -07002991void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002992 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002993 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002994 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2995 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002996 return;
2997 }
2998
Vishnu Nairc519ff72021-01-21 08:23:08 -08002999 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003000 if (focusedToken == token) {
3001 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003002 return;
3003 }
3004
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07003005 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
3006 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003007 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07003008 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003009}
3010
3011void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003012 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003013 if (ATRACE_ENABLED()) {
3014 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003015 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003016 ATRACE_NAME(message.c_str());
3017 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003018#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003019 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003020#endif
3021
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003022 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3023 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003024 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003025 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003026 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003027 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003028
3029 // Publish the event.
3030 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003031 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3032 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003033 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003034 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3035 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003036
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003037 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003038 status = connection->inputPublisher
3039 .publishKeyEvent(dispatchEntry->seq,
3040 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3041 keyEntry.source, keyEntry.displayId,
3042 std::move(hmac), dispatchEntry->resolvedAction,
3043 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3044 keyEntry.scanCode, keyEntry.metaState,
3045 keyEntry.repeatCount, keyEntry.downTime,
3046 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003047 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003048 }
3049
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003050 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003051 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003052
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003053 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003054 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003055
chaviw82357092020-01-28 13:13:06 -08003056 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003057 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003058 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3059 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003060 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003061 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3062 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003063 // Don't apply window scale here since we don't want scale to affect raw
3064 // coordinates. The scale will be sent back to the client and applied
3065 // later when requesting relative coordinates.
3066 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3067 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003068 }
3069 usingCoords = scaledCoords;
3070 }
3071 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003072 // We don't want the dispatch target to know.
3073 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003074 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003075 scaledCoords[i].clear();
3076 }
3077 usingCoords = scaledCoords;
3078 }
3079 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003080
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003081 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003082
3083 // Publish the motion event.
3084 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003085 .publishMotionEvent(dispatchEntry->seq,
3086 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003087 motionEntry.deviceId, motionEntry.source,
3088 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003089 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003090 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003091 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003092 motionEntry.edgeFlags, motionEntry.metaState,
3093 motionEntry.buttonState,
3094 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003095 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003096 motionEntry.xPrecision, motionEntry.yPrecision,
3097 motionEntry.xCursorPosition,
3098 motionEntry.yCursorPosition,
Evan Rosky84f07f02021-04-16 10:42:42 -07003099 dispatchEntry->displaySize.x,
3100 dispatchEntry->displaySize.y,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003101 motionEntry.downTime, motionEntry.eventTime,
3102 motionEntry.pointerCount,
3103 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003104 break;
3105 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003106
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003107 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003108 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003109 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003110 focusEntry.id,
3111 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003112 mInTouchMode);
3113 break;
3114 }
3115
Prabir Pradhan99987712020-11-10 18:43:05 -08003116 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3117 const auto& captureEntry =
3118 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3119 status = connection->inputPublisher
3120 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
3121 captureEntry.pointerCaptureEnabled);
3122 break;
3123 }
3124
arthurhungb89ccb02020-12-30 16:19:01 +08003125 case EventEntry::Type::DRAG: {
3126 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3127 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3128 dragEntry.id, dragEntry.x,
3129 dragEntry.y,
3130 dragEntry.isExiting);
3131 break;
3132 }
3133
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003134 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003135 case EventEntry::Type::DEVICE_RESET:
3136 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003137 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Chris Yef59a2f42020-10-16 12:55:26 -07003138 NamedEnum::string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003139 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003140 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003141 }
3142
3143 // Check the result.
3144 if (status) {
3145 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003146 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003147 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003148 "This is unexpected because the wait queue is empty, so the pipe "
3149 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003150 "event to it, status=%s(%d)",
3151 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3152 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003153 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3154 } else {
3155 // Pipe is full and we are waiting for the app to finish process some events
3156 // before sending more events to it.
3157#if DEBUG_DISPATCH_CYCLE
3158 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003159 "waiting for the application to catch up",
3160 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003161#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003162 }
3163 } else {
3164 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003165 "status=%s(%d)",
3166 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3167 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003168 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3169 }
3170 return;
3171 }
3172
3173 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003174 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3175 connection->outboundQueue.end(),
3176 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003177 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003178 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003179 if (connection->responsive) {
3180 mAnrTracker.insert(dispatchEntry->timeoutTime,
3181 connection->inputChannel->getConnectionToken());
3182 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003183 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003184 }
3185}
3186
chaviw09c8d2d2020-08-24 15:48:26 -07003187std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3188 size_t size;
3189 switch (event.type) {
3190 case VerifiedInputEvent::Type::KEY: {
3191 size = sizeof(VerifiedKeyEvent);
3192 break;
3193 }
3194 case VerifiedInputEvent::Type::MOTION: {
3195 size = sizeof(VerifiedMotionEvent);
3196 break;
3197 }
3198 }
3199 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3200 return mHmacKeyManager.sign(start, size);
3201}
3202
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003203const std::array<uint8_t, 32> InputDispatcher::getSignature(
3204 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3205 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3206 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3207 // Only sign events up and down events as the purely move events
3208 // are tied to their up/down counterparts so signing would be redundant.
3209 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3210 verifiedEvent.actionMasked = actionMasked;
3211 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003212 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003213 }
3214 return INVALID_HMAC;
3215}
3216
3217const std::array<uint8_t, 32> InputDispatcher::getSignature(
3218 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3219 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3220 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3221 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003222 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003223}
3224
Michael Wrightd02c5b62014-02-10 15:10:22 -08003225void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003226 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003227 bool handled, nsecs_t consumeTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003228#if DEBUG_DISPATCH_CYCLE
3229 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003230 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003231#endif
3232
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003233 if (connection->status == Connection::STATUS_BROKEN ||
3234 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003235 return;
3236 }
3237
3238 // Notify other system components and prepare to start the next dispatch cycle.
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003239 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled, consumeTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003240}
3241
3242void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003243 const sp<Connection>& connection,
3244 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003245#if DEBUG_DISPATCH_CYCLE
3246 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003247 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003248#endif
3249
3250 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003251 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003252 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003253 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003254 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003255
3256 // The connection appears to be unrecoverably broken.
3257 // Ignore already broken or zombie connections.
3258 if (connection->status == Connection::STATUS_NORMAL) {
3259 connection->status = Connection::STATUS_BROKEN;
3260
3261 if (notify) {
3262 // Notify other system components.
3263 onDispatchCycleBrokenLocked(currentTime, connection);
3264 }
3265 }
3266}
3267
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003268void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3269 while (!queue.empty()) {
3270 DispatchEntry* dispatchEntry = queue.front();
3271 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003272 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003273 }
3274}
3275
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003276void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003277 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003278 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003279 }
3280 delete dispatchEntry;
3281}
3282
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003283int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3284 std::scoped_lock _l(mLock);
3285 sp<Connection> connection = getConnectionLocked(connectionToken);
3286 if (connection == nullptr) {
3287 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3288 connectionToken.get(), events);
3289 return 0; // remove the callback
3290 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003291
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003292 bool notify;
3293 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3294 if (!(events & ALOOPER_EVENT_INPUT)) {
3295 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3296 "events=0x%x",
3297 connection->getInputChannelName().c_str(), events);
3298 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003299 }
3300
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003301 nsecs_t currentTime = now();
3302 bool gotOne = false;
3303 status_t status = OK;
3304 for (;;) {
3305 Result<InputPublisher::ConsumerResponse> result =
3306 connection->inputPublisher.receiveConsumerResponse();
3307 if (!result.ok()) {
3308 status = result.error().code();
3309 break;
3310 }
3311
3312 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3313 const InputPublisher::Finished& finish =
3314 std::get<InputPublisher::Finished>(*result);
3315 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3316 finish.consumeTime);
3317 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
3318 // TODO(b/167947340): Report this data to LatencyTracker
3319 }
3320 gotOne = true;
3321 }
3322 if (gotOne) {
3323 runCommandsLockedInterruptible();
3324 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003325 return 1;
3326 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327 }
3328
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003329 notify = status != DEAD_OBJECT || !connection->monitor;
3330 if (notify) {
3331 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3332 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3333 status);
3334 }
3335 } else {
3336 // Monitor channels are never explicitly unregistered.
3337 // We do it automatically when the remote endpoint is closed so don't warn about them.
3338 const bool stillHaveWindowHandle =
3339 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3340 notify = !connection->monitor && stillHaveWindowHandle;
3341 if (notify) {
3342 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3343 connection->getInputChannelName().c_str(), events);
3344 }
3345 }
3346
3347 // Remove the channel.
3348 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3349 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003350}
3351
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003352void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003353 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003354 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003355 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003356 }
3357}
3358
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003359void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003360 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003361 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3362 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3363}
3364
3365void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3366 const CancelationOptions& options,
3367 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3368 for (const auto& it : monitorsByDisplay) {
3369 const std::vector<Monitor>& monitors = it.second;
3370 for (const Monitor& monitor : monitors) {
3371 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003372 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003373 }
3374}
3375
Michael Wrightd02c5b62014-02-10 15:10:22 -08003376void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003377 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003378 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003379 if (connection == nullptr) {
3380 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003381 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003382
3383 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003384}
3385
3386void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3387 const sp<Connection>& connection, const CancelationOptions& options) {
3388 if (connection->status == Connection::STATUS_BROKEN) {
3389 return;
3390 }
3391
3392 nsecs_t currentTime = now();
3393
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003394 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003395 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003396
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003397 if (cancelationEvents.empty()) {
3398 return;
3399 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003400#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003401 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3402 "with reality: %s, mode=%d.",
3403 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3404 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003405#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003406
3407 InputTarget target;
3408 sp<InputWindowHandle> windowHandle =
3409 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3410 if (windowHandle != nullptr) {
3411 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003412 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003413 target.globalScaleFactor = windowInfo->globalScaleFactor;
3414 }
3415 target.inputChannel = connection->inputChannel;
3416 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3417
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003418 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003419 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003420 switch (cancelationEventEntry->type) {
3421 case EventEntry::Type::KEY: {
3422 logOutboundKeyDetails("cancel - ",
3423 static_cast<const KeyEntry&>(*cancelationEventEntry));
3424 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003425 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003426 case EventEntry::Type::MOTION: {
3427 logOutboundMotionDetails("cancel - ",
3428 static_cast<const MotionEntry&>(*cancelationEventEntry));
3429 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003430 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003431 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08003432 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3433 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003434 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Chris Yef59a2f42020-10-16 12:55:26 -07003435 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003436 break;
3437 }
3438 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003439 case EventEntry::Type::DEVICE_RESET:
3440 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003441 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003442 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003443 break;
3444 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003445 }
3446
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003447 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3448 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003449 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003450
3451 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003452}
3453
Svet Ganov5d3bc372020-01-26 23:11:07 -08003454void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3455 const sp<Connection>& connection) {
3456 if (connection->status == Connection::STATUS_BROKEN) {
3457 return;
3458 }
3459
3460 nsecs_t currentTime = now();
3461
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003462 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003463 connection->inputState.synthesizePointerDownEvents(currentTime);
3464
3465 if (downEvents.empty()) {
3466 return;
3467 }
3468
3469#if DEBUG_OUTBOUND_EVENT_DETAILS
3470 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3471 connection->getInputChannelName().c_str(), downEvents.size());
3472#endif
3473
3474 InputTarget target;
3475 sp<InputWindowHandle> windowHandle =
3476 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3477 if (windowHandle != nullptr) {
3478 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003479 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003480 target.globalScaleFactor = windowInfo->globalScaleFactor;
3481 }
3482 target.inputChannel = connection->inputChannel;
3483 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3484
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003485 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003486 switch (downEventEntry->type) {
3487 case EventEntry::Type::MOTION: {
3488 logOutboundMotionDetails("down - ",
3489 static_cast<const MotionEntry&>(*downEventEntry));
3490 break;
3491 }
3492
3493 case EventEntry::Type::KEY:
3494 case EventEntry::Type::FOCUS:
3495 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003496 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003497 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003498 case EventEntry::Type::SENSOR:
3499 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003500 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003501 NamedEnum::string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003502 break;
3503 }
3504 }
3505
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003506 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3507 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003508 }
3509
3510 startDispatchCycleLocked(currentTime, connection);
3511}
3512
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003513std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3514 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003515 ALOG_ASSERT(pointerIds.value != 0);
3516
3517 uint32_t splitPointerIndexMap[MAX_POINTERS];
3518 PointerProperties splitPointerProperties[MAX_POINTERS];
3519 PointerCoords splitPointerCoords[MAX_POINTERS];
3520
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003521 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003522 uint32_t splitPointerCount = 0;
3523
3524 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003525 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003526 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003527 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003528 uint32_t pointerId = uint32_t(pointerProperties.id);
3529 if (pointerIds.hasBit(pointerId)) {
3530 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3531 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3532 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003533 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003534 splitPointerCount += 1;
3535 }
3536 }
3537
3538 if (splitPointerCount != pointerIds.count()) {
3539 // This is bad. We are missing some of the pointers that we expected to deliver.
3540 // Most likely this indicates that we received an ACTION_MOVE events that has
3541 // different pointer ids than we expected based on the previous ACTION_DOWN
3542 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3543 // in this way.
3544 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003545 "we expected there to be %d pointers. This probably means we received "
3546 "a broken sequence of pointer ids from the input device.",
3547 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003548 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003549 }
3550
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003551 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003552 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003553 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3554 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003555 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3556 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003557 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003558 uint32_t pointerId = uint32_t(pointerProperties.id);
3559 if (pointerIds.hasBit(pointerId)) {
3560 if (pointerIds.count() == 1) {
3561 // The first/last pointer went down/up.
3562 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003563 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003564 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3565 ? AMOTION_EVENT_ACTION_CANCEL
3566 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003567 } else {
3568 // A secondary pointer went down/up.
3569 uint32_t splitPointerIndex = 0;
3570 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3571 splitPointerIndex += 1;
3572 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003573 action = maskedAction |
3574 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003575 }
3576 } else {
3577 // An unrelated pointer changed.
3578 action = AMOTION_EVENT_ACTION_MOVE;
3579 }
3580 }
3581
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003582 int32_t newId = mIdGenerator.nextId();
3583 if (ATRACE_ENABLED()) {
3584 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3585 ") to MotionEvent(id=0x%" PRIx32 ").",
3586 originalMotionEntry.id, newId);
3587 ATRACE_NAME(message.c_str());
3588 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003589 std::unique_ptr<MotionEntry> splitMotionEntry =
3590 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3591 originalMotionEntry.deviceId, originalMotionEntry.source,
3592 originalMotionEntry.displayId,
3593 originalMotionEntry.policyFlags, action,
3594 originalMotionEntry.actionButton,
3595 originalMotionEntry.flags, originalMotionEntry.metaState,
3596 originalMotionEntry.buttonState,
3597 originalMotionEntry.classification,
3598 originalMotionEntry.edgeFlags,
3599 originalMotionEntry.xPrecision,
3600 originalMotionEntry.yPrecision,
3601 originalMotionEntry.xCursorPosition,
3602 originalMotionEntry.yCursorPosition,
3603 originalMotionEntry.downTime, splitPointerCount,
3604 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003605
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003606 if (originalMotionEntry.injectionState) {
3607 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003608 splitMotionEntry->injectionState->refCount += 1;
3609 }
3610
3611 return splitMotionEntry;
3612}
3613
3614void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3615#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003616 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003617#endif
3618
3619 bool needWake;
3620 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003621 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003622
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003623 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3624 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3625 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003626 } // release lock
3627
3628 if (needWake) {
3629 mLooper->wake();
3630 }
3631}
3632
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003633/**
3634 * If one of the meta shortcuts is detected, process them here:
3635 * Meta + Backspace -> generate BACK
3636 * Meta + Enter -> generate HOME
3637 * This will potentially overwrite keyCode and metaState.
3638 */
3639void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003640 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003641 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3642 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3643 if (keyCode == AKEYCODE_DEL) {
3644 newKeyCode = AKEYCODE_BACK;
3645 } else if (keyCode == AKEYCODE_ENTER) {
3646 newKeyCode = AKEYCODE_HOME;
3647 }
3648 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003649 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003650 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003651 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003652 keyCode = newKeyCode;
3653 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3654 }
3655 } else if (action == AKEY_EVENT_ACTION_UP) {
3656 // In order to maintain a consistent stream of up and down events, check to see if the key
3657 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3658 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003659 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003660 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003661 auto replacementIt = mReplacedKeys.find(replacement);
3662 if (replacementIt != mReplacedKeys.end()) {
3663 keyCode = replacementIt->second;
3664 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003665 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3666 }
3667 }
3668}
3669
Michael Wrightd02c5b62014-02-10 15:10:22 -08003670void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3671#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003672 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3673 "policyFlags=0x%x, action=0x%x, "
3674 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3675 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3676 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3677 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003678#endif
3679 if (!validateKeyEvent(args->action)) {
3680 return;
3681 }
3682
3683 uint32_t policyFlags = args->policyFlags;
3684 int32_t flags = args->flags;
3685 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003686 // InputDispatcher tracks and generates key repeats on behalf of
3687 // whatever notifies it, so repeatCount should always be set to 0
3688 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003689 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3690 policyFlags |= POLICY_FLAG_VIRTUAL;
3691 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3692 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003693 if (policyFlags & POLICY_FLAG_FUNCTION) {
3694 metaState |= AMETA_FUNCTION_ON;
3695 }
3696
3697 policyFlags |= POLICY_FLAG_TRUSTED;
3698
Michael Wright78f24442014-08-06 15:55:28 -07003699 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003700 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003701
Michael Wrightd02c5b62014-02-10 15:10:22 -08003702 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003703 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003704 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3705 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003706
Michael Wright2b3c3302018-03-02 17:19:13 +00003707 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003708 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003709 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3710 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003711 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003712 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003713
Michael Wrightd02c5b62014-02-10 15:10:22 -08003714 bool needWake;
3715 { // acquire lock
3716 mLock.lock();
3717
3718 if (shouldSendKeyToInputFilterLocked(args)) {
3719 mLock.unlock();
3720
3721 policyFlags |= POLICY_FLAG_FILTERED;
3722 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3723 return; // event was consumed by the filter
3724 }
3725
3726 mLock.lock();
3727 }
3728
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003729 std::unique_ptr<KeyEntry> newEntry =
3730 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3731 args->displayId, policyFlags, args->action, flags,
3732 keyCode, args->scanCode, metaState, repeatCount,
3733 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003734
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003735 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003736 mLock.unlock();
3737 } // release lock
3738
3739 if (needWake) {
3740 mLooper->wake();
3741 }
3742}
3743
3744bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3745 return mInputFilterEnabled;
3746}
3747
3748void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3749#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003750 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3751 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003752 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3753 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003754 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003755 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3756 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3757 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3758 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003759 for (uint32_t i = 0; i < args->pointerCount; i++) {
3760 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003761 "x=%f, y=%f, pressure=%f, size=%f, "
3762 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3763 "orientation=%f",
3764 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3765 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3766 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3767 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3768 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3769 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3770 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3771 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3772 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3773 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003774 }
3775#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003776 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3777 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003778 return;
3779 }
3780
3781 uint32_t policyFlags = args->policyFlags;
3782 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003783
3784 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003785 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003786 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3787 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003788 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003789 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003790
3791 bool needWake;
3792 { // acquire lock
3793 mLock.lock();
3794
3795 if (shouldSendMotionToInputFilterLocked(args)) {
3796 mLock.unlock();
3797
3798 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003799 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003800 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3801 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003802 args->metaState, args->buttonState, args->classification, transform,
3803 args->xPrecision, args->yPrecision, args->xCursorPosition,
Evan Rosky84f07f02021-04-16 10:42:42 -07003804 args->yCursorPosition, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
3805 AMOTION_EVENT_INVALID_DISPLAY_SIZE, args->downTime, args->eventTime,
chaviw9eaa22c2020-07-01 16:21:27 -07003806 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003807
3808 policyFlags |= POLICY_FLAG_FILTERED;
3809 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3810 return; // event was consumed by the filter
3811 }
3812
3813 mLock.lock();
3814 }
3815
3816 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003817 std::unique_ptr<MotionEntry> newEntry =
3818 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3819 args->source, args->displayId, policyFlags,
3820 args->action, args->actionButton, args->flags,
3821 args->metaState, args->buttonState,
3822 args->classification, args->edgeFlags,
3823 args->xPrecision, args->yPrecision,
3824 args->xCursorPosition, args->yCursorPosition,
3825 args->downTime, args->pointerCount,
3826 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003827
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003828 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003829 mLock.unlock();
3830 } // release lock
3831
3832 if (needWake) {
3833 mLooper->wake();
3834 }
3835}
3836
Chris Yef59a2f42020-10-16 12:55:26 -07003837void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
3838#if DEBUG_INBOUND_EVENT_DETAILS
3839 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3840 " sensorType=%s",
3841 args->id, args->eventTime, args->deviceId, args->source,
3842 NamedEnum::string(args->sensorType).c_str());
3843#endif
3844
3845 bool needWake;
3846 { // acquire lock
3847 mLock.lock();
3848
3849 // Just enqueue a new sensor event.
3850 std::unique_ptr<SensorEntry> newEntry =
3851 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
3852 args->source, 0 /* policyFlags*/, args->hwTimestamp,
3853 args->sensorType, args->accuracy,
3854 args->accuracyChanged, args->values);
3855
3856 needWake = enqueueInboundEventLocked(std::move(newEntry));
3857 mLock.unlock();
3858 } // release lock
3859
3860 if (needWake) {
3861 mLooper->wake();
3862 }
3863}
3864
Chris Yefb552902021-02-03 17:18:37 -08003865void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
3866#if DEBUG_INBOUND_EVENT_DETAILS
3867 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
3868 args->deviceId, args->isOn);
3869#endif
3870 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
3871}
3872
Michael Wrightd02c5b62014-02-10 15:10:22 -08003873bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003874 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003875}
3876
3877void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3878#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003879 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003880 "switchMask=0x%08x",
3881 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003882#endif
3883
3884 uint32_t policyFlags = args->policyFlags;
3885 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003886 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003887}
3888
3889void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3890#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003891 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3892 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003893#endif
3894
3895 bool needWake;
3896 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003897 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003898
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003899 std::unique_ptr<DeviceResetEntry> newEntry =
3900 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3901 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003902 } // release lock
3903
3904 if (needWake) {
3905 mLooper->wake();
3906 }
3907}
3908
Prabir Pradhan7e186182020-11-10 13:56:45 -08003909void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3910#if DEBUG_INBOUND_EVENT_DETAILS
3911 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3912 args->enabled ? "true" : "false");
3913#endif
3914
Prabir Pradhan99987712020-11-10 18:43:05 -08003915 bool needWake;
3916 { // acquire lock
3917 std::scoped_lock _l(mLock);
3918 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
3919 args->enabled);
3920 needWake = enqueueInboundEventLocked(std::move(entry));
3921 } // release lock
3922
3923 if (needWake) {
3924 mLooper->wake();
3925 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003926}
3927
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003928InputEventInjectionResult InputDispatcher::injectInputEvent(
3929 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3930 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003931#if DEBUG_INBOUND_EVENT_DETAILS
3932 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003933 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3934 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003935#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003936 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003937
3938 policyFlags |= POLICY_FLAG_INJECTED;
3939 if (hasInjectionPermission(injectorPid, injectorUid)) {
3940 policyFlags |= POLICY_FLAG_TRUSTED;
3941 }
3942
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003943 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003944 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003945 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003946 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3947 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003948 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003949 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003950 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003951
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003952 int32_t flags = incomingKey.getFlags();
3953 int32_t keyCode = incomingKey.getKeyCode();
3954 int32_t metaState = incomingKey.getMetaState();
3955 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003956 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003957 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003958 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003959 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3960 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3961 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003963 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3964 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003965 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003966
3967 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3968 android::base::Timer t;
3969 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3970 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3971 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3972 std::to_string(t.duration().count()).c_str());
3973 }
3974 }
3975
3976 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003977 std::unique_ptr<KeyEntry> injectedEntry =
3978 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3979 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3980 incomingKey.getDisplayId(), policyFlags, action,
3981 flags, keyCode, incomingKey.getScanCode(), metaState,
3982 incomingKey.getRepeatCount(),
3983 incomingKey.getDownTime());
3984 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003985 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003986 }
3987
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003988 case AINPUT_EVENT_TYPE_MOTION: {
3989 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3990 int32_t action = motionEvent->getAction();
3991 size_t pointerCount = motionEvent->getPointerCount();
3992 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3993 int32_t actionButton = motionEvent->getActionButton();
3994 int32_t displayId = motionEvent->getDisplayId();
3995 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003996 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003997 }
3998
3999 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4000 nsecs_t eventTime = motionEvent->getEventTime();
4001 android::base::Timer t;
4002 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4003 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4004 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4005 std::to_string(t.duration().count()).c_str());
4006 }
4007 }
4008
4009 mLock.lock();
4010 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
4011 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004012 std::unique_ptr<MotionEntry> injectedEntry =
4013 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
4014 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
4015 motionEvent->getDisplayId(), policyFlags, action,
4016 actionButton, motionEvent->getFlags(),
4017 motionEvent->getMetaState(),
4018 motionEvent->getButtonState(),
4019 motionEvent->getClassification(),
4020 motionEvent->getEdgeFlags(),
4021 motionEvent->getXPrecision(),
4022 motionEvent->getYPrecision(),
4023 motionEvent->getRawXCursorPosition(),
4024 motionEvent->getRawYCursorPosition(),
4025 motionEvent->getDownTime(),
4026 uint32_t(pointerCount), pointerProperties,
4027 samplePointerCoords, motionEvent->getXOffset(),
4028 motionEvent->getYOffset());
4029 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004030 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
4031 sampleEventTimes += 1;
4032 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004033 std::unique_ptr<MotionEntry> nextInjectedEntry =
4034 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
4035 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
4036 motionEvent->getDisplayId(), policyFlags,
4037 action, actionButton, motionEvent->getFlags(),
4038 motionEvent->getMetaState(),
4039 motionEvent->getButtonState(),
4040 motionEvent->getClassification(),
4041 motionEvent->getEdgeFlags(),
4042 motionEvent->getXPrecision(),
4043 motionEvent->getYPrecision(),
4044 motionEvent->getRawXCursorPosition(),
4045 motionEvent->getRawYCursorPosition(),
4046 motionEvent->getDownTime(),
4047 uint32_t(pointerCount), pointerProperties,
4048 samplePointerCoords,
4049 motionEvent->getXOffset(),
4050 motionEvent->getYOffset());
4051 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004052 }
4053 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004054 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004055
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004056 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004057 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004058 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004059 }
4060
4061 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004062 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004063 injectionState->injectionIsAsync = true;
4064 }
4065
4066 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004067 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004068
4069 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004070 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004071 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004072 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004073 }
4074
4075 mLock.unlock();
4076
4077 if (needWake) {
4078 mLooper->wake();
4079 }
4080
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004081 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004082 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004083 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004084
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004085 if (syncMode == InputEventInjectionSync::NONE) {
4086 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004087 } else {
4088 for (;;) {
4089 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004090 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004091 break;
4092 }
4093
4094 nsecs_t remainingTimeout = endTime - now();
4095 if (remainingTimeout <= 0) {
4096#if DEBUG_INJECTION
4097 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004098 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004099#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004100 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004101 break;
4102 }
4103
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004104 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004105 }
4106
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004107 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4108 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004109 while (injectionState->pendingForegroundDispatches != 0) {
4110#if DEBUG_INJECTION
4111 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004112 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004113#endif
4114 nsecs_t remainingTimeout = endTime - now();
4115 if (remainingTimeout <= 0) {
4116#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004117 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4118 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004119#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004120 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004121 break;
4122 }
4123
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004124 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004125 }
4126 }
4127 }
4128
4129 injectionState->release();
4130 } // release lock
4131
4132#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004133 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004134 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004135#endif
4136
4137 return injectionResult;
4138}
4139
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004140std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004141 std::array<uint8_t, 32> calculatedHmac;
4142 std::unique_ptr<VerifiedInputEvent> result;
4143 switch (event.getType()) {
4144 case AINPUT_EVENT_TYPE_KEY: {
4145 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4146 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4147 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004148 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004149 break;
4150 }
4151 case AINPUT_EVENT_TYPE_MOTION: {
4152 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4153 VerifiedMotionEvent verifiedMotionEvent =
4154 verifiedMotionEventFromMotionEvent(motionEvent);
4155 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004156 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004157 break;
4158 }
4159 default: {
4160 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4161 return nullptr;
4162 }
4163 }
4164 if (calculatedHmac == INVALID_HMAC) {
4165 return nullptr;
4166 }
4167 if (calculatedHmac != event.getHmac()) {
4168 return nullptr;
4169 }
4170 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004171}
4172
Michael Wrightd02c5b62014-02-10 15:10:22 -08004173bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004174 return injectorUid == 0 ||
4175 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004176}
4177
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004178void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004179 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004180 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004181 if (injectionState) {
4182#if DEBUG_INJECTION
4183 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004184 "injectorPid=%d, injectorUid=%d",
4185 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004186#endif
4187
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004188 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004189 // Log the outcome since the injector did not wait for the injection result.
4190 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004191 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004192 ALOGV("Asynchronous input event injection succeeded.");
4193 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004194 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004195 ALOGW("Asynchronous input event injection failed.");
4196 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004197 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004198 ALOGW("Asynchronous input event injection permission denied.");
4199 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004200 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004201 ALOGW("Asynchronous input event injection timed out.");
4202 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004203 case InputEventInjectionResult::PENDING:
4204 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4205 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004206 }
4207 }
4208
4209 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004210 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004211 }
4212}
4213
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004214void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4215 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004216 if (injectionState) {
4217 injectionState->pendingForegroundDispatches += 1;
4218 }
4219}
4220
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004221void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4222 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004223 if (injectionState) {
4224 injectionState->pendingForegroundDispatches -= 1;
4225
4226 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004227 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004228 }
4229 }
4230}
4231
Vishnu Nairad321cd2020-08-20 16:40:21 -07004232const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004233 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004234 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
4235 auto it = mWindowHandlesByDisplay.find(displayId);
4236 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004237}
4238
Michael Wrightd02c5b62014-02-10 15:10:22 -08004239sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004240 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004241 if (windowHandleToken == nullptr) {
4242 return nullptr;
4243 }
4244
Arthur Hungb92218b2018-08-14 12:00:21 +08004245 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004246 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004247 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004248 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004249 return windowHandle;
4250 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004251 }
4252 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004253 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004254}
4255
Vishnu Nairad321cd2020-08-20 16:40:21 -07004256sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4257 int displayId) const {
4258 if (windowHandleToken == nullptr) {
4259 return nullptr;
4260 }
4261
4262 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
4263 if (windowHandle->getToken() == windowHandleToken) {
4264 return windowHandle;
4265 }
4266 }
4267 return nullptr;
4268}
4269
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004270sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
4271 const sp<InputWindowHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004272 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004273 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00004274 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004275 if (handle->getId() == windowHandle->getId() &&
4276 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004277 if (windowHandle->getInfo()->displayId != it.first) {
4278 ALOGE("Found window %s in display %" PRId32
4279 ", but it should belong to display %" PRId32,
4280 windowHandle->getName().c_str(), it.first,
4281 windowHandle->getInfo()->displayId);
4282 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004283 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004284 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004285 }
4286 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004287 return nullptr;
4288}
4289
4290sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
4291 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4292 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004293}
4294
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004295bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
4296 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4297 const bool noInputChannel =
4298 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4299 if (connection != nullptr && noInputChannel) {
4300 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4301 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4302 return false;
4303 }
4304
4305 if (connection == nullptr) {
4306 if (!noInputChannel) {
4307 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4308 }
4309 return false;
4310 }
4311 if (!connection->responsive) {
4312 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4313 return false;
4314 }
4315 return true;
4316}
4317
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004318std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4319 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004320 auto connectionIt = mConnectionsByToken.find(token);
4321 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004322 return nullptr;
4323 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004324 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004325}
4326
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004327void InputDispatcher::updateWindowHandlesForDisplayLocked(
4328 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
4329 if (inputWindowHandles.empty()) {
4330 // Remove all handles on a display if there are no windows left.
4331 mWindowHandlesByDisplay.erase(displayId);
4332 return;
4333 }
4334
4335 // Since we compare the pointer of input window handles across window updates, we need
4336 // to make sure the handle object for the same window stays unchanged across updates.
4337 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07004338 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004339 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004340 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004341 }
4342
4343 std::vector<sp<InputWindowHandle>> newHandles;
4344 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
4345 if (!handle->updateInfo()) {
4346 // handle no longer valid
4347 continue;
4348 }
4349
4350 const InputWindowInfo* info = handle->getInfo();
4351 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4352 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4353 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01004354 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4355 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
4356 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004357 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004358 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004359 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004360 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004361 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004362 }
4363
4364 if (info->displayId != displayId) {
4365 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4366 handle->getName().c_str(), displayId, info->displayId);
4367 continue;
4368 }
4369
Robert Carredd13602020-04-13 17:24:34 -07004370 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4371 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004372 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004373 oldHandle->updateFrom(handle);
4374 newHandles.push_back(oldHandle);
4375 } else {
4376 newHandles.push_back(handle);
4377 }
4378 }
4379
4380 // Insert or replace
4381 mWindowHandlesByDisplay[displayId] = newHandles;
4382}
4383
Arthur Hung72d8dc32020-03-28 00:48:39 +00004384void InputDispatcher::setInputWindows(
4385 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4386 { // acquire lock
4387 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004388 for (const auto& [displayId, handles] : handlesPerDisplay) {
4389 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004390 }
4391 }
4392 // Wake up poll loop since it may need to make new input dispatching choices.
4393 mLooper->wake();
4394}
4395
Arthur Hungb92218b2018-08-14 12:00:21 +08004396/**
4397 * Called from InputManagerService, update window handle list by displayId that can receive input.
4398 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4399 * If set an empty list, remove all handles from the specific display.
4400 * For focused handle, check if need to change and send a cancel event to previous one.
4401 * For removed handle, check if need to send a cancel event if already in touch.
4402 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004403void InputDispatcher::setInputWindowsLocked(
4404 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004405 if (DEBUG_FOCUS) {
4406 std::string windowList;
4407 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4408 windowList += iwh->getName() + " ";
4409 }
4410 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4411 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004412
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004413 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4414 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4415 const bool noInputWindow =
4416 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4417 if (noInputWindow && window->getToken() != nullptr) {
4418 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4419 window->getName().c_str());
4420 window->releaseChannel();
4421 }
4422 }
4423
Arthur Hung72d8dc32020-03-28 00:48:39 +00004424 // Copy old handles for release if they are no longer present.
4425 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004426
Arthur Hung72d8dc32020-03-28 00:48:39 +00004427 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004428
Vishnu Nair958da932020-08-21 17:12:37 -07004429 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4430 if (mLastHoverWindowHandle &&
4431 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4432 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004433 mLastHoverWindowHandle = nullptr;
4434 }
4435
Vishnu Nairc519ff72021-01-21 08:23:08 -08004436 std::optional<FocusResolver::FocusChanges> changes =
4437 mFocusResolver.setInputWindows(displayId, windowHandles);
4438 if (changes) {
4439 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004440 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004441
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004442 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4443 mTouchStatesByDisplay.find(displayId);
4444 if (stateIt != mTouchStatesByDisplay.end()) {
4445 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004446 for (size_t i = 0; i < state.windows.size();) {
4447 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004448 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004449 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004450 ALOGD("Touched window was removed: %s in display %" PRId32,
4451 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004452 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004453 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004454 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4455 if (touchedInputChannel != nullptr) {
4456 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4457 "touched window was removed");
4458 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004459 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004460 state.windows.erase(state.windows.begin() + i);
4461 } else {
4462 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004463 }
4464 }
arthurhungb89ccb02020-12-30 16:19:01 +08004465
arthurhung6d4bed92021-03-17 11:59:33 +08004466 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004467 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004468 if (mDragState &&
4469 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004470 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004471 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004472 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004473 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004474
Arthur Hung72d8dc32020-03-28 00:48:39 +00004475 // Release information for windows that are no longer present.
4476 // This ensures that unused input channels are released promptly.
4477 // Otherwise, they might stick around until the window handle is destroyed
4478 // which might not happen until the next GC.
4479 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004480 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004481 if (DEBUG_FOCUS) {
4482 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004483 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004484 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004485 // To avoid making too many calls into the compat framework, only
4486 // check for window flags when windows are going away.
4487 // TODO(b/157929241) : delete this. This is only needed temporarily
4488 // in order to gather some data about the flag usage
4489 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4490 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4491 oldWindowHandle->getName().c_str());
4492 if (mCompatService != nullptr) {
4493 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4494 oldWindowHandle->getInfo()->ownerUid);
4495 }
4496 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004497 }
chaviw291d88a2019-02-14 10:33:58 -08004498 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004499}
4500
4501void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004502 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004503 if (DEBUG_FOCUS) {
4504 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4505 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4506 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004507 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004508 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004509
Chris Yea209fde2020-07-22 13:54:51 -07004510 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004511 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004512
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004513 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4514 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004515 }
4516
Chris Yea209fde2020-07-22 13:54:51 -07004517 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004518 if (inputApplicationHandle != nullptr) {
4519 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4520 } else {
4521 mFocusedApplicationHandlesByDisplay.erase(displayId);
4522 }
4523
4524 // No matter what the old focused application was, stop waiting on it because it is
4525 // no longer focused.
4526 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004527 } // release lock
4528
4529 // Wake up poll loop since it may need to make new input dispatching choices.
4530 mLooper->wake();
4531}
4532
Tiger Huang721e26f2018-07-24 22:26:19 +08004533/**
4534 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4535 * the display not specified.
4536 *
4537 * We track any unreleased events for each window. If a window loses the ability to receive the
4538 * released event, we will send a cancel event to it. So when the focused display is changed, we
4539 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4540 * display. The display-specified events won't be affected.
4541 */
4542void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004543 if (DEBUG_FOCUS) {
4544 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4545 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004546 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004547 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004548
4549 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004550 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004551 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004552 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004553 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004554 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004555 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004556 CancelationOptions
4557 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4558 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004559 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004560 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4561 }
4562 }
4563 mFocusedDisplayId = displayId;
4564
Chris Ye3c2d6f52020-08-09 10:39:48 -07004565 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004566 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004567 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004568
Vishnu Nairad321cd2020-08-20 16:40:21 -07004569 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004570 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004571 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004572 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004573 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004574 }
4575 }
4576 }
4577
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004578 if (DEBUG_FOCUS) {
4579 logDispatchStateLocked();
4580 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004581 } // release lock
4582
4583 // Wake up poll loop since it may need to make new input dispatching choices.
4584 mLooper->wake();
4585}
4586
Michael Wrightd02c5b62014-02-10 15:10:22 -08004587void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004588 if (DEBUG_FOCUS) {
4589 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4590 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004591
4592 bool changed;
4593 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004594 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004595
4596 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4597 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004598 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004599 }
4600
4601 if (mDispatchEnabled && !enabled) {
4602 resetAndDropEverythingLocked("dispatcher is being disabled");
4603 }
4604
4605 mDispatchEnabled = enabled;
4606 mDispatchFrozen = frozen;
4607 changed = true;
4608 } else {
4609 changed = false;
4610 }
4611
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004612 if (DEBUG_FOCUS) {
4613 logDispatchStateLocked();
4614 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004615 } // release lock
4616
4617 if (changed) {
4618 // Wake up poll loop since it may need to make new input dispatching choices.
4619 mLooper->wake();
4620 }
4621}
4622
4623void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004624 if (DEBUG_FOCUS) {
4625 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4626 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004627
4628 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004629 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004630
4631 if (mInputFilterEnabled == enabled) {
4632 return;
4633 }
4634
4635 mInputFilterEnabled = enabled;
4636 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4637 } // release lock
4638
4639 // Wake up poll loop since there might be work to do to drop everything.
4640 mLooper->wake();
4641}
4642
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004643void InputDispatcher::setInTouchMode(bool inTouchMode) {
4644 std::scoped_lock lock(mLock);
4645 mInTouchMode = inTouchMode;
4646}
4647
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004648void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4649 if (opacity < 0 || opacity > 1) {
4650 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4651 return;
4652 }
4653
4654 std::scoped_lock lock(mLock);
4655 mMaximumObscuringOpacityForTouch = opacity;
4656}
4657
4658void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4659 std::scoped_lock lock(mLock);
4660 mBlockUntrustedTouchesMode = mode;
4661}
4662
arthurhungb89ccb02020-12-30 16:19:01 +08004663bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4664 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004665 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004666 if (DEBUG_FOCUS) {
4667 ALOGD("Trivial transfer to same window.");
4668 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004669 return true;
4670 }
4671
Michael Wrightd02c5b62014-02-10 15:10:22 -08004672 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004673 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004674
chaviwfbe5d9c2018-12-26 12:23:37 -08004675 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4676 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004677 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004678 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004679 return false;
4680 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004681 if (DEBUG_FOCUS) {
4682 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4683 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4684 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004685 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004686 if (DEBUG_FOCUS) {
4687 ALOGD("Cannot transfer focus because windows are on different displays.");
4688 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004689 return false;
4690 }
4691
4692 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004693 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4694 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004695 for (size_t i = 0; i < state.windows.size(); i++) {
4696 const TouchedWindow& touchedWindow = state.windows[i];
4697 if (touchedWindow.windowHandle == fromWindowHandle) {
4698 int32_t oldTargetFlags = touchedWindow.targetFlags;
4699 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004700
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004701 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004702
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004703 int32_t newTargetFlags = oldTargetFlags &
4704 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4705 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004706 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004707
arthurhungb89ccb02020-12-30 16:19:01 +08004708 // Store the dragging window.
4709 if (isDragDrop) {
arthurhung6d4bed92021-03-17 11:59:33 +08004710 mDragState = std::make_unique<DragState>(toWindowHandle);
arthurhungb89ccb02020-12-30 16:19:01 +08004711 }
4712
Jeff Brownf086ddb2014-02-11 14:28:48 -08004713 found = true;
4714 goto Found;
4715 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004716 }
4717 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004718 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004719
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004720 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004721 if (DEBUG_FOCUS) {
4722 ALOGD("Focus transfer failed because from window did not have focus.");
4723 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004724 return false;
4725 }
4726
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004727 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4728 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004729 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004730 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004731 CancelationOptions
4732 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4733 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004734 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004735 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004736 }
4737
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004738 if (DEBUG_FOCUS) {
4739 logDispatchStateLocked();
4740 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004741 } // release lock
4742
4743 // Wake up poll loop since it may need to make new input dispatching choices.
4744 mLooper->wake();
4745 return true;
4746}
4747
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00004748// Binder call
4749bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
4750 sp<IBinder> fromToken;
4751 { // acquire lock
4752 std::scoped_lock _l(mLock);
4753
4754 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(destChannelToken);
4755 if (toWindowHandle == nullptr) {
4756 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
4757 return false;
4758 }
4759
4760 const int32_t displayId = toWindowHandle->getInfo()->displayId;
4761
4762 auto touchStateIt = mTouchStatesByDisplay.find(displayId);
4763 if (touchStateIt == mTouchStatesByDisplay.end()) {
4764 ALOGD("Could not transfer touch because the display %" PRId32 " is not being touched",
4765 displayId);
4766 return false;
4767 }
4768
4769 TouchState& state = touchStateIt->second;
4770 if (state.windows.size() != 1) {
4771 ALOGW("Cannot transfer touch state because there are %zu windows being touched",
4772 state.windows.size());
4773 return false;
4774 }
4775 const TouchedWindow& touchedWindow = state.windows[0];
4776 fromToken = touchedWindow.windowHandle->getToken();
4777 } // release lock
4778
4779 return transferTouchFocus(fromToken, destChannelToken);
4780}
4781
Michael Wrightd02c5b62014-02-10 15:10:22 -08004782void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004783 if (DEBUG_FOCUS) {
4784 ALOGD("Resetting and dropping all events (%s).", reason);
4785 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004786
4787 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4788 synthesizeCancelationEventsForAllConnectionsLocked(options);
4789
4790 resetKeyRepeatLocked();
4791 releasePendingEventLocked();
4792 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004793 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004794
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004795 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004796 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004797 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004798 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004799}
4800
4801void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004802 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004803 dumpDispatchStateLocked(dump);
4804
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004805 std::istringstream stream(dump);
4806 std::string line;
4807
4808 while (std::getline(stream, line, '\n')) {
4809 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004810 }
4811}
4812
Prabir Pradhan99987712020-11-10 18:43:05 -08004813std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4814 std::string dump;
4815
4816 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4817 toString(mFocusedWindowRequestedPointerCapture));
4818
4819 std::string windowName = "None";
4820 if (mWindowTokenWithPointerCapture) {
4821 const sp<InputWindowHandle> captureWindowHandle =
4822 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4823 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4824 : "token has capture without window";
4825 }
4826 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4827
4828 return dump;
4829}
4830
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004831void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004832 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4833 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4834 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004835 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004836
Tiger Huang721e26f2018-07-24 22:26:19 +08004837 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4838 dump += StringPrintf(INDENT "FocusedApplications:\n");
4839 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4840 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004841 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004842 const std::chrono::duration timeout =
4843 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004844 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004845 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004846 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004847 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004848 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004849 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004850 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004851
Vishnu Nairc519ff72021-01-21 08:23:08 -08004852 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08004853 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004854
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004855 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004856 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004857 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4858 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004859 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004860 state.displayId, toString(state.down), toString(state.split),
4861 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004862 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004863 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004864 for (size_t i = 0; i < state.windows.size(); i++) {
4865 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004866 dump += StringPrintf(INDENT4
4867 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4868 i, touchedWindow.windowHandle->getName().c_str(),
4869 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004870 }
4871 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004872 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004873 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004874 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004875 dump += INDENT3 "Portal windows:\n";
4876 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004877 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004878 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4879 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004880 }
4881 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004882 }
4883 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004884 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004885 }
4886
arthurhung6d4bed92021-03-17 11:59:33 +08004887 if (mDragState) {
4888 dump += StringPrintf(INDENT "DragState:\n");
4889 mDragState->dump(dump, INDENT2);
4890 }
4891
Arthur Hungb92218b2018-08-14 12:00:21 +08004892 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004893 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004894 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004895 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004896 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004897 dump += INDENT2 "Windows:\n";
4898 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004899 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004900 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004901
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004902 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004903 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004904 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004905 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004906 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00004907 "applicationInfo.name=%s, "
4908 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004909 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004910 i, windowInfo->name.c_str(), windowInfo->id,
4911 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004912 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004913 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004914 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004915 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004916 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004917 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004918 windowInfo->frameLeft, windowInfo->frameTop,
4919 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004920 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00004921 windowInfo->applicationInfo.name.c_str(),
4922 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004923 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004924 dump += StringPrintf(", inputFeatures=%s",
4925 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004926 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004927 "ms, trustedOverlay=%s, hasToken=%s, "
4928 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004929 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004930 millis(windowInfo->dispatchingTimeout),
4931 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004932 toString(windowInfo->token != nullptr),
4933 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004934 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004935 }
4936 } else {
4937 dump += INDENT2 "Windows: <none>\n";
4938 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004939 }
4940 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004941 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004942 }
4943
Michael Wright3dd60e22019-03-27 22:06:44 +00004944 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004945 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004946 const std::vector<Monitor>& monitors = it.second;
4947 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4948 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004949 }
4950 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004951 const std::vector<Monitor>& monitors = it.second;
4952 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4953 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004954 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004955 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004956 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004957 }
4958
4959 nsecs_t currentTime = now();
4960
4961 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004962 if (!mRecentQueue.empty()) {
4963 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004964 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004965 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004966 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004967 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004968 }
4969 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004970 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004971 }
4972
4973 // Dump event currently being dispatched.
4974 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004975 dump += INDENT "PendingEvent:\n";
4976 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004977 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004978 dump += StringPrintf(", age=%" PRId64 "ms\n",
4979 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004980 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004981 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004982 }
4983
4984 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004985 if (!mInboundQueue.empty()) {
4986 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004987 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004988 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004989 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004990 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004991 }
4992 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004993 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004994 }
4995
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004996 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004997 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004998 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4999 const KeyReplacement& replacement = pair.first;
5000 int32_t newKeyCode = pair.second;
5001 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005002 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005003 }
5004 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005005 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005006 }
5007
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005008 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005009 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005010 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005011 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005012 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005013 connection->inputChannel->getFd().get(),
5014 connection->getInputChannelName().c_str(),
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005015 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005016 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005017
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005018 if (!connection->outboundQueue.empty()) {
5019 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5020 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005021 dump += dumpQueue(connection->outboundQueue, currentTime);
5022
Michael Wrightd02c5b62014-02-10 15:10:22 -08005023 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005024 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005025 }
5026
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005027 if (!connection->waitQueue.empty()) {
5028 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5029 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005030 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005031 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005032 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005033 }
5034 }
5035 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005036 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005037 }
5038
5039 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005040 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5041 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005042 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005043 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005044 }
5045
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005046 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005047 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5048 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5049 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005050}
5051
Michael Wright3dd60e22019-03-27 22:06:44 +00005052void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5053 const size_t numMonitors = monitors.size();
5054 for (size_t i = 0; i < numMonitors; i++) {
5055 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005056 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005057 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5058 dump += "\n";
5059 }
5060}
5061
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005062class LooperEventCallback : public LooperCallback {
5063public:
5064 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5065 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5066
5067private:
5068 std::function<int(int events)> mCallback;
5069};
5070
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005071Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Garfield Tan15601662020-09-22 15:32:38 -07005072#if DEBUG_CHANNEL_CREATION
5073 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005074#endif
5075
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005076 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005077 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005078 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005079
5080 if (result) {
5081 return base::Error(result) << "Failed to open input channel pair with name " << name;
5082 }
5083
Michael Wrightd02c5b62014-02-10 15:10:22 -08005084 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005085 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005086 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005087 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005088 sp<Connection> connection =
5089 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005090
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005091 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5092 ALOGE("Created a new connection, but the token %p is already known", token.get());
5093 }
5094 mConnectionsByToken.emplace(token, connection);
5095
5096 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5097 this, std::placeholders::_1, token);
5098
5099 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005100 } // release lock
5101
5102 // Wake the looper because some connections have changed.
5103 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005104 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005105}
5106
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005107Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5108 bool isGestureMonitor,
5109 const std::string& name,
5110 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005111 std::shared_ptr<InputChannel> serverChannel;
5112 std::unique_ptr<InputChannel> clientChannel;
5113 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5114 if (result) {
5115 return base::Error(result) << "Failed to open input channel pair with name " << name;
5116 }
5117
Michael Wright3dd60e22019-03-27 22:06:44 +00005118 { // acquire lock
5119 std::scoped_lock _l(mLock);
5120
5121 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005122 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5123 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005124 }
5125
Garfield Tan15601662020-09-22 15:32:38 -07005126 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005127 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005128 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005129
5130 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5131 ALOGE("Created a new connection, but the token %p is already known", token.get());
5132 }
5133 mConnectionsByToken.emplace(token, connection);
5134 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5135 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005136
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005137 auto& monitorsByDisplay =
5138 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005139 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005140
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005141 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wright3dd60e22019-03-27 22:06:44 +00005142 }
Garfield Tan15601662020-09-22 15:32:38 -07005143
Michael Wright3dd60e22019-03-27 22:06:44 +00005144 // Wake the looper because some connections have changed.
5145 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005146 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005147}
5148
Garfield Tan15601662020-09-22 15:32:38 -07005149status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005150 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005151 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005152
Garfield Tan15601662020-09-22 15:32:38 -07005153 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005154 if (status) {
5155 return status;
5156 }
5157 } // release lock
5158
5159 // Wake the poll loop because removing the connection may have changed the current
5160 // synchronization state.
5161 mLooper->wake();
5162 return OK;
5163}
5164
Garfield Tan15601662020-09-22 15:32:38 -07005165status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5166 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005167 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005168 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005169 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005170 return BAD_VALUE;
5171 }
5172
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005173 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005174
Michael Wrightd02c5b62014-02-10 15:10:22 -08005175 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005176 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005177 }
5178
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005179 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005180
5181 nsecs_t currentTime = now();
5182 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5183
5184 connection->status = Connection::STATUS_ZOMBIE;
5185 return OK;
5186}
5187
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005188void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5189 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5190 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005191}
5192
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005193void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005194 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005195 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005196 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005197 std::vector<Monitor>& monitors = it->second;
5198 const size_t numMonitors = monitors.size();
5199 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005200 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005201 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5202 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005203 monitors.erase(monitors.begin() + i);
5204 break;
5205 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005206 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005207 if (monitors.empty()) {
5208 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005209 } else {
5210 ++it;
5211 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005212 }
5213}
5214
Michael Wright3dd60e22019-03-27 22:06:44 +00005215status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5216 { // acquire lock
5217 std::scoped_lock _l(mLock);
5218 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5219
5220 if (!foundDisplayId) {
5221 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5222 return BAD_VALUE;
5223 }
5224 int32_t displayId = foundDisplayId.value();
5225
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005226 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5227 mTouchStatesByDisplay.find(displayId);
5228 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005229 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5230 return BAD_VALUE;
5231 }
5232
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005233 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005234 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005235 std::optional<int32_t> foundDeviceId;
5236 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005237 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005238 requestingChannel = touchedMonitor.monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005239 foundDeviceId = state.deviceId;
5240 }
5241 }
5242 if (!foundDeviceId || !state.down) {
5243 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005244 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005245 return BAD_VALUE;
5246 }
5247 int32_t deviceId = foundDeviceId.value();
5248
5249 // Send cancel events to all the input channels we're stealing from.
5250 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005251 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005252 options.deviceId = deviceId;
5253 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005254 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005255 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005256 std::shared_ptr<InputChannel> channel =
5257 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005258 if (channel != nullptr) {
5259 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005260 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005261 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005262 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005263 canceledWindows += "]";
5264 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5265 canceledWindows.c_str());
5266
Michael Wright3dd60e22019-03-27 22:06:44 +00005267 // Then clear the current touch state so we stop dispatching to them as well.
5268 state.filterNonMonitors();
5269 }
5270 return OK;
5271}
5272
Prabir Pradhan99987712020-11-10 18:43:05 -08005273void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5274 { // acquire lock
5275 std::scoped_lock _l(mLock);
5276 if (DEBUG_FOCUS) {
5277 const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
5278 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5279 windowHandle != nullptr ? windowHandle->getName().c_str()
5280 : "token without window");
5281 }
5282
Vishnu Nairc519ff72021-01-21 08:23:08 -08005283 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005284 if (focusedToken != windowToken) {
5285 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5286 enabled ? "enable" : "disable");
5287 return;
5288 }
5289
5290 if (enabled == mFocusedWindowRequestedPointerCapture) {
5291 ALOGW("Ignoring request to %s Pointer Capture: "
5292 "window has %s requested pointer capture.",
5293 enabled ? "enable" : "disable", enabled ? "already" : "not");
5294 return;
5295 }
5296
5297 mFocusedWindowRequestedPointerCapture = enabled;
5298 setPointerCaptureLocked(enabled);
5299 } // release lock
5300
5301 // Wake the thread to process command entries.
5302 mLooper->wake();
5303}
5304
Michael Wright3dd60e22019-03-27 22:06:44 +00005305std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5306 const sp<IBinder>& token) {
5307 for (const auto& it : mGestureMonitorsByDisplay) {
5308 const std::vector<Monitor>& monitors = it.second;
5309 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005310 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005311 return it.first;
5312 }
5313 }
5314 }
5315 return std::nullopt;
5316}
5317
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005318std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5319 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5320 if (gesturePid.has_value()) {
5321 return gesturePid;
5322 }
5323 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5324}
5325
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005326sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005327 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005328 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005329 }
5330
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005331 for (const auto& [token, connection] : mConnectionsByToken) {
5332 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005333 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005334 }
5335 }
Robert Carr4e670e52018-08-15 13:26:12 -07005336
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005337 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005338}
5339
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005340std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5341 sp<Connection> connection = getConnectionLocked(connectionToken);
5342 if (connection == nullptr) {
5343 return "<nullptr>";
5344 }
5345 return connection->getInputChannelName();
5346}
5347
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005348void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005349 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005350 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005351}
5352
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005353void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5354 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10005355 bool handled, nsecs_t consumeTime) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005356 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5357 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005358 commandEntry->connection = connection;
5359 commandEntry->eventTime = currentTime;
5360 commandEntry->seq = seq;
5361 commandEntry->handled = handled;
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10005362 commandEntry->consumeTime = consumeTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005363 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005364}
5365
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005366void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5367 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005368 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005369 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005370
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005371 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5372 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005373 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005374 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005375}
5376
Vishnu Nairad321cd2020-08-20 16:40:21 -07005377void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5378 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005379 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5380 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005381 commandEntry->oldToken = oldToken;
5382 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005383 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005384}
5385
arthurhungf452d0b2021-01-06 00:19:52 +08005386void InputDispatcher::notifyDropWindowLocked(const sp<IBinder>& token, float x, float y) {
5387 std::unique_ptr<CommandEntry> commandEntry =
5388 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyDropWindowLockedInterruptible);
5389 commandEntry->newToken = token;
5390 commandEntry->x = x;
5391 commandEntry->y = y;
5392 postCommandLocked(std::move(commandEntry));
5393}
5394
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005395void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5396 if (connection == nullptr) {
5397 LOG_ALWAYS_FATAL("Caller must check for nullness");
5398 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005399 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5400 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005401 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005402 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005403 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005404 return;
5405 }
5406 /**
5407 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5408 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5409 * has changed. This could cause newer entries to time out before the already dispatched
5410 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5411 * processes the events linearly. So providing information about the oldest entry seems to be
5412 * most useful.
5413 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005414 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005415 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5416 std::string reason =
5417 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005418 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005419 ns2ms(currentWait),
5420 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005421 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005422 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005423
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005424 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5425
5426 // Stop waking up for events on this connection, it is already unresponsive
5427 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005428}
5429
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005430void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5431 std::string reason =
5432 StringPrintf("%s does not have a focused window", application->getName().c_str());
5433 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005434
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005435 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5436 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5437 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005438 postCommandLocked(std::move(commandEntry));
5439}
5440
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005441void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5442 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5443 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5444 commandEntry->obscuringPackage = obscuringPackage;
5445 postCommandLocked(std::move(commandEntry));
5446}
5447
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005448void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
5449 const std::string& reason) {
5450 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5451 updateLastAnrStateLocked(windowLabel, reason);
5452}
5453
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005454void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5455 const std::string& reason) {
5456 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005457 updateLastAnrStateLocked(windowLabel, reason);
5458}
5459
5460void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5461 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005462 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005463 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005464 struct tm tm;
5465 localtime_r(&t, &tm);
5466 char timestr[64];
5467 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005468 mLastAnrState.clear();
5469 mLastAnrState += INDENT "ANR:\n";
5470 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005471 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5472 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005473 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005474}
5475
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005476void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005477 mLock.unlock();
5478
5479 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5480
5481 mLock.lock();
5482}
5483
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005484void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005485 sp<Connection> connection = commandEntry->connection;
5486
5487 if (connection->status != Connection::STATUS_ZOMBIE) {
5488 mLock.unlock();
5489
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005490 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005491
5492 mLock.lock();
5493 }
5494}
5495
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005496void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005497 sp<IBinder> oldToken = commandEntry->oldToken;
5498 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005499 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005500 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005501 mLock.lock();
5502}
5503
arthurhungf452d0b2021-01-06 00:19:52 +08005504void InputDispatcher::doNotifyDropWindowLockedInterruptible(CommandEntry* commandEntry) {
5505 sp<IBinder> newToken = commandEntry->newToken;
5506 mLock.unlock();
5507 mPolicy->notifyDropWindow(newToken, commandEntry->x, commandEntry->y);
5508 mLock.lock();
5509}
5510
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005511void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005512 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005513
5514 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5515
5516 mLock.lock();
5517}
5518
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005519void InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005520 mLock.unlock();
5521
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005522 mPolicy->notifyWindowUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005523
5524 mLock.lock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005525}
5526
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005527void InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005528 mLock.unlock();
5529
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005530 mPolicy->notifyMonitorUnresponsive(commandEntry->pid, commandEntry->reason);
5531
5532 mLock.lock();
5533}
5534
5535void InputDispatcher::doNotifyWindowResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5536 mLock.unlock();
5537
5538 mPolicy->notifyWindowResponsive(commandEntry->connectionToken);
5539
5540 mLock.lock();
5541}
5542
5543void InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5544 mLock.unlock();
5545
5546 mPolicy->notifyMonitorResponsive(commandEntry->pid);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005547
5548 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005549}
5550
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005551void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5552 mLock.unlock();
5553
5554 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5555
5556 mLock.lock();
5557}
5558
Michael Wrightd02c5b62014-02-10 15:10:22 -08005559void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5560 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005561 KeyEntry& entry = *(commandEntry->keyEntry);
5562 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005563
5564 mLock.unlock();
5565
Michael Wright2b3c3302018-03-02 17:19:13 +00005566 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005567 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005568 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005569 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5570 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005571 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005572 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005573
5574 mLock.lock();
5575
5576 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005577 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005578 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005579 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005580 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005581 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5582 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005583 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005584}
5585
chaviwfd6d3512019-03-25 13:23:49 -07005586void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5587 mLock.unlock();
5588 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5589 mLock.lock();
5590}
5591
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005592/**
5593 * Connection is responsive if it has no events in the waitQueue that are older than the
5594 * current time.
5595 */
5596static bool isConnectionResponsive(const Connection& connection) {
5597 const nsecs_t currentTime = now();
5598 for (const DispatchEntry* entry : connection.waitQueue) {
5599 if (entry->timeoutTime < currentTime) {
5600 return false;
5601 }
5602 }
5603 return true;
5604}
5605
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005606void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005607 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005608 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005609 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005610 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005611
5612 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005613 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005614 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005615 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005616 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005617 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005618 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005619 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005620 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5621 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005622 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005623 // TODO(b/167947340): report event latency information to the policy
5624 // Example: mPolicy->reportFinishedEvent(commandEntry->eventId, eventEntry.eventTime,
5625 // dispatchEntry->deliveryTime, commandEntry->consumeTime,
5626 // finishTime);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005627
5628 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005629 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005630 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005631 restartEvent =
5632 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005633 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005634 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005635 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5636 handled);
5637 } else {
5638 restartEvent = false;
5639 }
5640
5641 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005642 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005643 // contents of the wait queue to have been drained, so we need to double-check
5644 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005645 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5646 if (dispatchEntryIt != connection->waitQueue.end()) {
5647 dispatchEntry = *dispatchEntryIt;
5648 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005649 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5650 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005651 if (!connection->responsive) {
5652 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005653 if (connection->responsive) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005654 // The connection was unresponsive, and now it's responsive.
5655 processConnectionResponsiveLocked(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005656 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005657 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005658 traceWaitQueueLength(*connection);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005659 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005660 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005661 traceOutboundQueueLength(*connection);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005662 } else {
5663 releaseDispatchEntry(dispatchEntry);
5664 }
5665 }
5666
5667 // Start the next dispatch cycle for this connection.
5668 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005669}
5670
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005671void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
5672 std::unique_ptr<CommandEntry> monitorUnresponsiveCommand = std::make_unique<CommandEntry>(
5673 &InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible);
5674 monitorUnresponsiveCommand->pid = pid;
5675 monitorUnresponsiveCommand->reason = std::move(reason);
5676 postCommandLocked(std::move(monitorUnresponsiveCommand));
5677}
5678
5679void InputDispatcher::sendWindowUnresponsiveCommandLocked(sp<IBinder> connectionToken,
5680 std::string reason) {
5681 std::unique_ptr<CommandEntry> windowUnresponsiveCommand = std::make_unique<CommandEntry>(
5682 &InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible);
5683 windowUnresponsiveCommand->connectionToken = std::move(connectionToken);
5684 windowUnresponsiveCommand->reason = std::move(reason);
5685 postCommandLocked(std::move(windowUnresponsiveCommand));
5686}
5687
5688void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
5689 std::unique_ptr<CommandEntry> monitorResponsiveCommand = std::make_unique<CommandEntry>(
5690 &InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible);
5691 monitorResponsiveCommand->pid = pid;
5692 postCommandLocked(std::move(monitorResponsiveCommand));
5693}
5694
5695void InputDispatcher::sendWindowResponsiveCommandLocked(sp<IBinder> connectionToken) {
5696 std::unique_ptr<CommandEntry> windowResponsiveCommand = std::make_unique<CommandEntry>(
5697 &InputDispatcher::doNotifyWindowResponsiveLockedInterruptible);
5698 windowResponsiveCommand->connectionToken = std::move(connectionToken);
5699 postCommandLocked(std::move(windowResponsiveCommand));
5700}
5701
5702/**
5703 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5704 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5705 * command entry to the command queue.
5706 */
5707void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5708 std::string reason) {
5709 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5710 if (connection.monitor) {
5711 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5712 reason.c_str());
5713 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5714 if (!pid.has_value()) {
5715 ALOGE("Could not find unresponsive monitor for connection %s",
5716 connection.inputChannel->getName().c_str());
5717 return;
5718 }
5719 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5720 return;
5721 }
5722 // If not a monitor, must be a window
5723 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5724 reason.c_str());
5725 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5726}
5727
5728/**
5729 * Tell the policy that a connection has become responsive so that it can stop ANR.
5730 */
5731void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5732 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5733 if (connection.monitor) {
5734 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5735 if (!pid.has_value()) {
5736 ALOGE("Could not find responsive monitor for connection %s",
5737 connection.inputChannel->getName().c_str());
5738 return;
5739 }
5740 sendMonitorResponsiveCommandLocked(pid.value());
5741 return;
5742 }
5743 // If not a monitor, must be a window
5744 sendWindowResponsiveCommandLocked(connectionToken);
5745}
5746
Michael Wrightd02c5b62014-02-10 15:10:22 -08005747bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005748 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005749 KeyEntry& keyEntry, bool handled) {
5750 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005751 if (!handled) {
5752 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005753 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005754 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005755 return false;
5756 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005757
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005758 // Get the fallback key state.
5759 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005760 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005761 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005762 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005763 connection->inputState.removeFallbackKey(originalKeyCode);
5764 }
5765
5766 if (handled || !dispatchEntry->hasForegroundTarget()) {
5767 // If the application handles the original key for which we previously
5768 // generated a fallback or if the window is not a foreground window,
5769 // then cancel the associated fallback key, if any.
5770 if (fallbackKeyCode != -1) {
5771 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005772#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005773 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005774 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005775 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005776#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005777 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005778 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005779
5780 mLock.unlock();
5781
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005782 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005783 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005784
5785 mLock.lock();
5786
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005787 // Cancel the fallback key.
5788 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005789 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005790 "application handled the original non-fallback key "
5791 "or is no longer a foreground target, "
5792 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005793 options.keyCode = fallbackKeyCode;
5794 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005795 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005796 connection->inputState.removeFallbackKey(originalKeyCode);
5797 }
5798 } else {
5799 // If the application did not handle a non-fallback key, first check
5800 // that we are in a good state to perform unhandled key event processing
5801 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005802 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005803 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005804#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005805 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005806 "since this is not an initial down. "
5807 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005808 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005809#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005810 return false;
5811 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005812
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005813 // Dispatch the unhandled key to the policy.
5814#if DEBUG_OUTBOUND_EVENT_DETAILS
5815 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005816 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005817 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005818#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005819 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005820
5821 mLock.unlock();
5822
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005823 bool fallback =
5824 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005825 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005826
5827 mLock.lock();
5828
5829 if (connection->status != Connection::STATUS_NORMAL) {
5830 connection->inputState.removeFallbackKey(originalKeyCode);
5831 return false;
5832 }
5833
5834 // Latch the fallback keycode for this key on an initial down.
5835 // The fallback keycode cannot change at any other point in the lifecycle.
5836 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005837 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005838 fallbackKeyCode = event.getKeyCode();
5839 } else {
5840 fallbackKeyCode = AKEYCODE_UNKNOWN;
5841 }
5842 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5843 }
5844
5845 ALOG_ASSERT(fallbackKeyCode != -1);
5846
5847 // Cancel the fallback key if the policy decides not to send it anymore.
5848 // We will continue to dispatch the key to the policy but we will no
5849 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005850 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5851 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005852#if DEBUG_OUTBOUND_EVENT_DETAILS
5853 if (fallback) {
5854 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005855 "as a fallback for %d, but on the DOWN it had requested "
5856 "to send %d instead. Fallback canceled.",
5857 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005858 } else {
5859 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005860 "but on the DOWN it had requested to send %d. "
5861 "Fallback canceled.",
5862 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005863 }
5864#endif
5865
5866 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5867 "canceling fallback, policy no longer desires it");
5868 options.keyCode = fallbackKeyCode;
5869 synthesizeCancelationEventsForConnectionLocked(connection, options);
5870
5871 fallback = false;
5872 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005873 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005874 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005875 }
5876 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005877
5878#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005879 {
5880 std::string msg;
5881 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5882 connection->inputState.getFallbackKeys();
5883 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005884 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005885 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005886 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005887 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005888 }
5889#endif
5890
5891 if (fallback) {
5892 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005893 keyEntry.eventTime = event.getEventTime();
5894 keyEntry.deviceId = event.getDeviceId();
5895 keyEntry.source = event.getSource();
5896 keyEntry.displayId = event.getDisplayId();
5897 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5898 keyEntry.keyCode = fallbackKeyCode;
5899 keyEntry.scanCode = event.getScanCode();
5900 keyEntry.metaState = event.getMetaState();
5901 keyEntry.repeatCount = event.getRepeatCount();
5902 keyEntry.downTime = event.getDownTime();
5903 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005904
5905#if DEBUG_OUTBOUND_EVENT_DETAILS
5906 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005907 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005908 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005909#endif
5910 return true; // restart the event
5911 } else {
5912#if DEBUG_OUTBOUND_EVENT_DETAILS
5913 ALOGD("Unhandled key event: No fallback key.");
5914#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005915
5916 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005917 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005918 }
5919 }
5920 return false;
5921}
5922
5923bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005924 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005925 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005926 return false;
5927}
5928
5929void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5930 mLock.unlock();
5931
Sean Stoutb4e0a592021-02-23 07:34:53 -08005932 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType,
5933 commandEntry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005934
5935 mLock.lock();
5936}
5937
Michael Wrightd02c5b62014-02-10 15:10:22 -08005938void InputDispatcher::traceInboundQueueLengthLocked() {
5939 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005940 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005941 }
5942}
5943
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005944void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005945 if (ATRACE_ENABLED()) {
5946 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005947 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
5948 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005949 }
5950}
5951
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005952void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005953 if (ATRACE_ENABLED()) {
5954 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005955 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
5956 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005957 }
5958}
5959
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005960void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005961 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005962
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005963 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005964 dumpDispatchStateLocked(dump);
5965
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005966 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005967 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005968 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005969 }
5970}
5971
5972void InputDispatcher::monitor() {
5973 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005974 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005975 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005976 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005977}
5978
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005979/**
5980 * Wake up the dispatcher and wait until it processes all events and commands.
5981 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5982 * this method can be safely called from any thread, as long as you've ensured that
5983 * the work you are interested in completing has already been queued.
5984 */
5985bool InputDispatcher::waitForIdle() {
5986 /**
5987 * Timeout should represent the longest possible time that a device might spend processing
5988 * events and commands.
5989 */
5990 constexpr std::chrono::duration TIMEOUT = 100ms;
5991 std::unique_lock lock(mLock);
5992 mLooper->wake();
5993 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5994 return result == std::cv_status::no_timeout;
5995}
5996
Vishnu Naire798b472020-07-23 13:52:21 -07005997/**
5998 * Sets focus to the window identified by the token. This must be called
5999 * after updating any input window handles.
6000 *
6001 * Params:
6002 * request.token - input channel token used to identify the window that should gain focus.
6003 * request.focusedToken - the token that the caller expects currently to be focused. If the
6004 * specified token does not match the currently focused window, this request will be dropped.
6005 * If the specified focused token matches the currently focused window, the call will succeed.
6006 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6007 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6008 * when requesting the focus change. This determines which request gets
6009 * precedence if there is a focus change request from another source such as pointer down.
6010 */
Vishnu Nair958da932020-08-21 17:12:37 -07006011void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6012 { // acquire lock
6013 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006014 std::optional<FocusResolver::FocusChanges> changes =
6015 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6016 if (changes) {
6017 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006018 }
6019 } // release lock
6020 // Wake up poll loop since it may need to make new input dispatching choices.
6021 mLooper->wake();
6022}
6023
Vishnu Nairc519ff72021-01-21 08:23:08 -08006024void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6025 if (changes.oldFocus) {
6026 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006027 if (focusedInputChannel) {
6028 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6029 "focus left window");
6030 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006031 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006032 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006033 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006034 if (changes.newFocus) {
6035 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006036 }
6037
Prabir Pradhan99987712020-11-10 18:43:05 -08006038 // If a window has pointer capture, then it must have focus. We need to ensure that this
6039 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6040 // If the window loses focus before it loses pointer capture, then the window can be in a state
6041 // where it has pointer capture but not focus, violating the contract. Therefore we must
6042 // dispatch the pointer capture event before the focus event. Since focus events are added to
6043 // the front of the queue (above), we add the pointer capture event to the front of the queue
6044 // after the focus events are added. This ensures the pointer capture event ends up at the
6045 // front.
6046 disablePointerCaptureForcedLocked();
6047
Vishnu Nairc519ff72021-01-21 08:23:08 -08006048 if (mFocusedDisplayId == changes.displayId) {
6049 notifyFocusChangedLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006050 }
6051}
Vishnu Nair958da932020-08-21 17:12:37 -07006052
Prabir Pradhan99987712020-11-10 18:43:05 -08006053void InputDispatcher::disablePointerCaptureForcedLocked() {
6054 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
6055 return;
6056 }
6057
6058 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6059
6060 if (mFocusedWindowRequestedPointerCapture) {
6061 mFocusedWindowRequestedPointerCapture = false;
6062 setPointerCaptureLocked(false);
6063 }
6064
6065 if (!mWindowTokenWithPointerCapture) {
6066 // No need to send capture changes because no window has capture.
6067 return;
6068 }
6069
6070 if (mPendingEvent != nullptr) {
6071 // Move the pending event to the front of the queue. This will give the chance
6072 // for the pending event to be dropped if it is a captured event.
6073 mInboundQueue.push_front(mPendingEvent);
6074 mPendingEvent = nullptr;
6075 }
6076
6077 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
6078 false /* hasCapture */);
6079 mInboundQueue.push_front(std::move(entry));
6080}
6081
Prabir Pradhan99987712020-11-10 18:43:05 -08006082void InputDispatcher::setPointerCaptureLocked(bool enabled) {
6083 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
6084 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
6085 commandEntry->enabled = enabled;
6086 postCommandLocked(std::move(commandEntry));
6087}
6088
6089void InputDispatcher::doSetPointerCaptureLockedInterruptible(
6090 android::inputdispatcher::CommandEntry* commandEntry) {
6091 mLock.unlock();
6092
6093 mPolicy->setPointerCapture(commandEntry->enabled);
6094
6095 mLock.lock();
6096}
6097
Garfield Tane84e6f92019-08-29 17:28:41 -07006098} // namespace android::inputdispatcher