blob: 3e80bd7d2c0681d59a464b9301ac40971e4e39fe [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 <statslog.h>
63#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070064#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080065
Michael Wright44753b12020-07-08 13:48:11 +010066#include <cerrno>
67#include <cinttypes>
68#include <climits>
69#include <cstddef>
70#include <ctime>
71#include <queue>
72#include <sstream>
73
74#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070075#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010076
Michael Wrightd02c5b62014-02-10 15:10:22 -080077#define INDENT " "
78#define INDENT2 " "
79#define INDENT3 " "
80#define INDENT4 " "
81
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080082using android::base::HwTimeoutMultiplier;
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
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700285/**
286 * Find the entry in std::unordered_map by value, and remove it.
287 * If more than one entry has the same value, then all matching
288 * key-value pairs will be removed.
289 *
290 * Return true if at least one value has been removed.
291 */
292template <typename K, typename V>
293static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
294 bool removed = false;
295 for (auto it = map.begin(); it != map.end();) {
296 if (it->second == value) {
297 it = map.erase(it);
298 removed = true;
299 } else {
300 it++;
301 }
302 }
303 return removed;
304}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800305
chaviwaf87b3e2019-10-01 16:59:28 -0700306static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
307 if (first == second) {
308 return true;
309 }
310
311 if (first == nullptr || second == nullptr) {
312 return false;
313 }
314
315 return first->getToken() == second->getToken();
316}
317
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000318static bool haveSameApplicationToken(const InputWindowInfo* first, const InputWindowInfo* second) {
319 if (first == nullptr || second == nullptr) {
320 return false;
321 }
322 return first->applicationInfo.token != nullptr &&
323 first->applicationInfo.token == second->applicationInfo.token;
324}
325
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800326static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
327 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
328}
329
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000330static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700331 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000332 int32_t inputTargetFlags) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900333 if (eventEntry->type == EventEntry::Type::MOTION) {
334 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
Prabir Pradhanbd527712021-03-09 19:17:09 -0800335 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) == 0) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900336 const ui::Transform identityTransform;
Prabir Pradhanbd527712021-03-09 19:17:09 -0800337 // Use identity transform for events that are not pointer events because their axes
338 // values do not represent on-screen coordinates, so they should not have any window
339 // transformations applied to them.
yunho.shinf4a80b82020-11-16 21:13:57 +0900340 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
341 1.0f /*globalScaleFactor*/);
342 }
343 }
344
chaviw1ff3d1e2020-07-01 15:53:47 -0700345 if (inputTarget.useDefaultPointerTransform()) {
346 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700347 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
chaviw1ff3d1e2020-07-01 15:53:47 -0700348 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000349 }
350
351 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
352 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
353
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700354 std::vector<PointerCoords> pointerCoords;
355 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000356
357 // Use the first pointer information to normalize all other pointers. This could be any pointer
358 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700359 // uses the transform for the normalized pointer.
360 const ui::Transform& firstPointerTransform =
361 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
362 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000363
364 // Iterate through all pointers in the event to normalize against the first.
365 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
366 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
367 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700368 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000369
370 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700371 // First, apply the current pointer's transform to update the coordinates into
372 // window space.
373 pointerCoords[pointerIndex].transform(currTransform);
374 // Next, apply the inverse transform of the normalized coordinates so the
375 // current coordinates are transformed into the normalized coordinate space.
376 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000377 }
378
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700379 std::unique_ptr<MotionEntry> combinedMotionEntry =
380 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
381 motionEntry.deviceId, motionEntry.source,
382 motionEntry.displayId, motionEntry.policyFlags,
383 motionEntry.action, motionEntry.actionButton,
384 motionEntry.flags, motionEntry.metaState,
385 motionEntry.buttonState, motionEntry.classification,
386 motionEntry.edgeFlags, motionEntry.xPrecision,
387 motionEntry.yPrecision, motionEntry.xCursorPosition,
388 motionEntry.yCursorPosition, motionEntry.downTime,
389 motionEntry.pointerCount, motionEntry.pointerProperties,
390 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000391
392 if (motionEntry.injectionState) {
393 combinedMotionEntry->injectionState = motionEntry.injectionState;
394 combinedMotionEntry->injectionState->refCount += 1;
395 }
396
397 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700398 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
399 firstPointerTransform, inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000400 return dispatchEntry;
401}
402
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700403static void addGestureMonitors(const std::vector<Monitor>& monitors,
404 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
405 float yOffset = 0) {
406 if (monitors.empty()) {
407 return;
408 }
409 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
410 for (const Monitor& monitor : monitors) {
411 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
412 }
413}
414
Garfield Tan15601662020-09-22 15:32:38 -0700415static status_t openInputChannelPair(const std::string& name,
416 std::shared_ptr<InputChannel>& serverChannel,
417 std::unique_ptr<InputChannel>& clientChannel) {
418 std::unique_ptr<InputChannel> uniqueServerChannel;
419 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
420
421 serverChannel = std::move(uniqueServerChannel);
422 return result;
423}
424
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500425template <typename T>
426static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
427 if (lhs == nullptr && rhs == nullptr) {
428 return true;
429 }
430 if (lhs == nullptr || rhs == nullptr) {
431 return false;
432 }
433 return *lhs == *rhs;
434}
435
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000436static sp<IPlatformCompatNative> getCompatService() {
437 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
438 if (service == nullptr) {
439 ALOGE("Failed to link to compat service");
440 return nullptr;
441 }
442 return interface_cast<IPlatformCompatNative>(service);
443}
444
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000445static KeyEvent createKeyEvent(const KeyEntry& entry) {
446 KeyEvent event;
447 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
448 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
449 entry.repeatCount, entry.downTime, entry.eventTime);
450 return event;
451}
452
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000453static std::optional<int32_t> findMonitorPidByToken(
454 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
455 const sp<IBinder>& token) {
456 for (const auto& it : monitorsByDisplay) {
457 const std::vector<Monitor>& monitors = it.second;
458 for (const Monitor& monitor : monitors) {
459 if (monitor.inputChannel->getConnectionToken() == token) {
460 return monitor.pid;
461 }
462 }
463 }
464 return std::nullopt;
465}
466
Michael Wrightd02c5b62014-02-10 15:10:22 -0800467// --- InputDispatcher ---
468
Garfield Tan00f511d2019-06-12 16:55:40 -0700469InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
470 : mPolicy(policy),
471 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700472 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800473 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700474 mAppSwitchSawKeyDown(false),
475 mAppSwitchDueTime(LONG_LONG_MAX),
476 mNextUnblockedEvent(nullptr),
477 mDispatchEnabled(false),
478 mDispatchFrozen(false),
479 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800480 // mInTouchMode will be initialized by the WindowManager to the default device config.
481 // To avoid leaking stack in case that call never comes, and for tests,
482 // initialize it here anyways.
483 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100484 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000485 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800486 mFocusedWindowRequestedPointerCapture(false),
487 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000488 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800489 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800490 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800491
Yi Kong9b14ac62018-07-17 13:48:38 -0700492 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800493
494 policy->getDispatcherConfiguration(&mConfig);
495}
496
497InputDispatcher::~InputDispatcher() {
498 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800499 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800500
501 resetKeyRepeatLocked();
502 releasePendingEventLocked();
503 drainInboundQueueLocked();
504 }
505
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700506 while (!mConnectionsByFd.empty()) {
507 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700508 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800509 }
510}
511
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700512status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700513 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700514 return ALREADY_EXISTS;
515 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700516 mThread = std::make_unique<InputThread>(
517 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
518 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700519}
520
521status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700522 if (mThread && mThread->isCallingThread()) {
523 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700524 return INVALID_OPERATION;
525 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700526 mThread.reset();
527 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700528}
529
Michael Wrightd02c5b62014-02-10 15:10:22 -0800530void InputDispatcher::dispatchOnce() {
531 nsecs_t nextWakeupTime = LONG_LONG_MAX;
532 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800533 std::scoped_lock _l(mLock);
534 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800535
536 // Run a dispatch loop if there are no pending commands.
537 // The dispatch loop might enqueue commands to run afterwards.
538 if (!haveCommandsLocked()) {
539 dispatchOnceInnerLocked(&nextWakeupTime);
540 }
541
542 // Run all pending commands if there are any.
543 // If any commands were run then force the next poll to wake up immediately.
544 if (runCommandsLockedInterruptible()) {
545 nextWakeupTime = LONG_LONG_MIN;
546 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800547
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700548 // If we are still waiting for ack on some events,
549 // we might have to wake up earlier to check if an app is anr'ing.
550 const nsecs_t nextAnrCheck = processAnrsLocked();
551 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
552
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800553 // We are about to enter an infinitely long sleep, because we have no commands or
554 // pending or queued events
555 if (nextWakeupTime == LONG_LONG_MAX) {
556 mDispatcherEnteredIdle.notify_all();
557 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800558 } // release lock
559
560 // Wait for callback or timeout or wake. (make sure we round up, not down)
561 nsecs_t currentTime = now();
562 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
563 mLooper->pollOnce(timeoutMillis);
564}
565
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700566/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500567 * Raise ANR if there is no focused window.
568 * Before the ANR is raised, do a final state check:
569 * 1. The currently focused application must be the same one we are waiting for.
570 * 2. Ensure we still don't have a focused window.
571 */
572void InputDispatcher::processNoFocusedWindowAnrLocked() {
573 // Check if the application that we are waiting for is still focused.
574 std::shared_ptr<InputApplicationHandle> focusedApplication =
575 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
576 if (focusedApplication == nullptr ||
577 focusedApplication->getApplicationToken() !=
578 mAwaitedFocusedApplication->getApplicationToken()) {
579 // Unexpected because we should have reset the ANR timer when focused application changed
580 ALOGE("Waited for a focused window, but focused application has already changed to %s",
581 focusedApplication->getName().c_str());
582 return; // The focused application has changed.
583 }
584
585 const sp<InputWindowHandle>& focusedWindowHandle =
586 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
587 if (focusedWindowHandle != nullptr) {
588 return; // We now have a focused window. No need for ANR.
589 }
590 onAnrLocked(mAwaitedFocusedApplication);
591}
592
593/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700594 * Check if any of the connections' wait queues have events that are too old.
595 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
596 * Return the time at which we should wake up next.
597 */
598nsecs_t InputDispatcher::processAnrsLocked() {
599 const nsecs_t currentTime = now();
600 nsecs_t nextAnrCheck = LONG_LONG_MAX;
601 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
602 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
603 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500604 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700605 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500606 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700607 return LONG_LONG_MIN;
608 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500609 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700610 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
611 }
612 }
613
614 // Check if any connection ANRs are due
615 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
616 if (currentTime < nextAnrCheck) { // most likely scenario
617 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
618 }
619
620 // If we reached here, we have an unresponsive connection.
621 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
622 if (connection == nullptr) {
623 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
624 return nextAnrCheck;
625 }
626 connection->responsive = false;
627 // Stop waking up for this unresponsive connection
628 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000629 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700630 return LONG_LONG_MIN;
631}
632
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500633std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700634 sp<InputWindowHandle> window = getWindowHandleLocked(token);
635 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500636 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700637 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500638 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700639}
640
Michael Wrightd02c5b62014-02-10 15:10:22 -0800641void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
642 nsecs_t currentTime = now();
643
Jeff Browndc5992e2014-04-11 01:27:26 -0700644 // Reset the key repeat timer whenever normal dispatch is suspended while the
645 // device is in a non-interactive state. This is to ensure that we abort a key
646 // repeat if the device is just coming out of sleep.
647 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800648 resetKeyRepeatLocked();
649 }
650
651 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
652 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100653 if (DEBUG_FOCUS) {
654 ALOGD("Dispatch frozen. Waiting some more.");
655 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800656 return;
657 }
658
659 // Optimize latency of app switches.
660 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
661 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
662 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
663 if (mAppSwitchDueTime < *nextWakeupTime) {
664 *nextWakeupTime = mAppSwitchDueTime;
665 }
666
667 // Ready to start a new event.
668 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700669 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700670 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800671 if (isAppSwitchDue) {
672 // The inbound queue is empty so the app switch key we were waiting
673 // for will never arrive. Stop waiting for it.
674 resetPendingAppSwitchLocked(false);
675 isAppSwitchDue = false;
676 }
677
678 // Synthesize a key repeat if appropriate.
679 if (mKeyRepeatState.lastKeyEntry) {
680 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
681 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
682 } else {
683 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
684 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
685 }
686 }
687 }
688
689 // Nothing to do if there is no pending event.
690 if (!mPendingEvent) {
691 return;
692 }
693 } else {
694 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700695 mPendingEvent = mInboundQueue.front();
696 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800697 traceInboundQueueLengthLocked();
698 }
699
700 // Poke user activity for this event.
701 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700702 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800703 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800704 }
705
706 // Now we have an event to dispatch.
707 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700708 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800709 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700710 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800711 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700712 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800713 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700714 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800715 }
716
717 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700718 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800719 }
720
721 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700722 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700723 const ConfigurationChangedEntry& typedEntry =
724 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700725 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700726 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700727 break;
728 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800729
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700730 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700731 const DeviceResetEntry& typedEntry =
732 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700733 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700734 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700735 break;
736 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800737
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100738 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700739 std::shared_ptr<FocusEntry> typedEntry =
740 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100741 dispatchFocusLocked(currentTime, typedEntry);
742 done = true;
743 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
744 break;
745 }
746
Prabir Pradhan99987712020-11-10 18:43:05 -0800747 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
748 const auto typedEntry =
749 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
750 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
751 done = true;
752 break;
753 }
754
arthurhungb89ccb02020-12-30 16:19:01 +0800755 case EventEntry::Type::DRAG: {
756 std::shared_ptr<DragEntry> typedEntry =
757 std::static_pointer_cast<DragEntry>(mPendingEvent);
758 dispatchDragLocked(currentTime, typedEntry);
759 done = true;
760 break;
761 }
762
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700763 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700764 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700765 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700766 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700767 resetPendingAppSwitchLocked(true);
768 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700769 } else if (dropReason == DropReason::NOT_DROPPED) {
770 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700771 }
772 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700773 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700774 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700775 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700776 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
777 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700778 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700779 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700780 break;
781 }
782
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700783 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700784 std::shared_ptr<MotionEntry> motionEntry =
785 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700786 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
787 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800788 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700789 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700790 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700791 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700792 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
793 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700794 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700795 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700796 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800797 }
Chris Yef59a2f42020-10-16 12:55:26 -0700798
799 case EventEntry::Type::SENSOR: {
800 std::shared_ptr<SensorEntry> sensorEntry =
801 std::static_pointer_cast<SensorEntry>(mPendingEvent);
802 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
803 dropReason = DropReason::APP_SWITCH;
804 }
805 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
806 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
807 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
808 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
809 dropReason = DropReason::STALE;
810 }
811 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
812 done = true;
813 break;
814 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800815 }
816
817 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700818 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700819 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800820 }
Michael Wright3a981722015-06-10 15:26:13 +0100821 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800822
823 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700824 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800825 }
826}
827
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700828/**
829 * Return true if the events preceding this incoming motion event should be dropped
830 * Return false otherwise (the default behaviour)
831 */
832bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700833 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700834 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700835
836 // Optimize case where the current application is unresponsive and the user
837 // decides to touch a window in a different application.
838 // If the application takes too long to catch up then we drop all events preceding
839 // the touch into the other window.
840 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700841 int32_t displayId = motionEntry.displayId;
842 int32_t x = static_cast<int32_t>(
843 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
844 int32_t y = static_cast<int32_t>(
845 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
846 sp<InputWindowHandle> touchedWindowHandle =
847 findTouchedWindowAtLocked(displayId, x, y, nullptr);
848 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700849 touchedWindowHandle->getApplicationToken() !=
850 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700851 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700852 ALOGI("Pruning input queue because user touched a different application while waiting "
853 "for %s",
854 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700855 return true;
856 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700857
858 // Alternatively, maybe there's a gesture monitor that could handle this event
859 std::vector<TouchedMonitor> gestureMonitors =
860 findTouchedGestureMonitorsLocked(displayId, {});
861 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
862 sp<Connection> connection =
863 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000864 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700865 // This monitor could take more input. Drop all events preceding this
866 // event, so that gesture monitor could get a chance to receive the stream
867 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
868 "responsive gesture monitor that may handle the event",
869 mAwaitedFocusedApplication->getName().c_str());
870 return true;
871 }
872 }
873 }
874
875 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
876 // yet been processed by some connections, the dispatcher will wait for these motion
877 // events to be processed before dispatching the key event. This is because these motion events
878 // may cause a new window to be launched, which the user might expect to receive focus.
879 // To prevent waiting forever for such events, just send the key to the currently focused window
880 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
881 ALOGD("Received a new pointer down event, stop waiting for events to process and "
882 "just send the pending key event to the focused window.");
883 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700884 }
885 return false;
886}
887
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700888bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700889 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700890 mInboundQueue.push_back(std::move(newEntry));
891 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800892 traceInboundQueueLengthLocked();
893
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700894 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700895 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700896 // Optimize app switch latency.
897 // If the application takes too long to catch up then we drop all events preceding
898 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700899 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700900 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700901 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700902 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700903 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700904 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800905#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700906 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800907#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700908 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700909 mAppSwitchSawKeyDown = false;
910 needWake = true;
911 }
912 }
913 }
914 break;
915 }
916
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700917 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700918 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
919 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700920 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800921 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700922 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800923 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100924 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700925 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
926 break;
927 }
928 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -0800929 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -0700930 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +0800931 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
932 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700933 // nothing to do
934 break;
935 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800936 }
937
938 return needWake;
939}
940
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700941void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -0700942 // Do not store sensor event in recent queue to avoid flooding the queue.
943 if (entry->type != EventEntry::Type::SENSOR) {
944 mRecentQueue.push_back(entry);
945 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700946 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700947 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800948 }
949}
950
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700951sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700952 int32_t y, TouchState* touchState,
953 bool addOutsideTargets,
arthurhungb89ccb02020-12-30 16:19:01 +0800954 bool addPortalWindows,
955 bool ignoreDragWindow) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700956 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
957 LOG_ALWAYS_FATAL(
958 "Must provide a valid touch state if adding portal windows or outside targets");
959 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800960 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700961 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800962 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
arthurhungb89ccb02020-12-30 16:19:01 +0800963 if (ignoreDragWindow && haveSameToken(windowHandle, touchState->dragWindow)) {
964 continue;
965 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800966 const InputWindowInfo* windowInfo = windowHandle->getInfo();
967 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100968 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800969
970 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100971 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
972 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
973 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800974 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800975 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700976 if (portalToDisplayId != ADISPLAY_ID_NONE &&
977 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800978 if (addPortalWindows) {
979 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700980 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800981 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700982 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700983 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800984 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985 // Found window.
986 return windowHandle;
987 }
988 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800989
Michael Wright44753b12020-07-08 13:48:11 +0100990 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700991 touchState->addOrUpdateWindow(windowHandle,
992 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
993 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800994 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800995 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800996 }
997 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700998 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800999}
1000
Garfield Tane84e6f92019-08-29 17:28:41 -07001001std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001002 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00001003 std::vector<TouchedMonitor> touchedMonitors;
1004
1005 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
1006 addGestureMonitors(monitors, touchedMonitors);
1007 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
1008 const InputWindowInfo* windowInfo = portalWindow->getInfo();
1009 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001010 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
1011 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +00001012 }
1013 return touchedMonitors;
1014}
1015
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001016void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001017 const char* reason;
1018 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001019 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -08001020#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001021 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001022#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001023 reason = "inbound event was dropped because the policy consumed it";
1024 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001025 case DropReason::DISABLED:
1026 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001027 ALOGI("Dropped event because input dispatch is disabled.");
1028 }
1029 reason = "inbound event was dropped because input dispatch is disabled";
1030 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001031 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001032 ALOGI("Dropped event because of pending overdue app switch.");
1033 reason = "inbound event was dropped because of pending overdue app switch";
1034 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001035 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001036 ALOGI("Dropped event because the current application is not responding and the user "
1037 "has started interacting with a different application.");
1038 reason = "inbound event was dropped because the current application is not responding "
1039 "and the user has started interacting with a different application";
1040 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001041 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001042 ALOGI("Dropped event because it is stale.");
1043 reason = "inbound event was dropped because it is stale";
1044 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001045 case DropReason::NO_POINTER_CAPTURE:
1046 ALOGI("Dropped event because there is no window with Pointer Capture.");
1047 reason = "inbound event was dropped because there is no window with Pointer Capture";
1048 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001049 case DropReason::NOT_DROPPED: {
1050 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001051 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001052 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001053 }
1054
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001055 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001056 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001057 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1058 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001059 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001060 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001061 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001062 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1063 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001064 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1065 synthesizeCancelationEventsForAllConnectionsLocked(options);
1066 } else {
1067 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1068 synthesizeCancelationEventsForAllConnectionsLocked(options);
1069 }
1070 break;
1071 }
Chris Yef59a2f42020-10-16 12:55:26 -07001072 case EventEntry::Type::SENSOR: {
1073 break;
1074 }
arthurhungb89ccb02020-12-30 16:19:01 +08001075 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1076 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001077 break;
1078 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001079 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001080 case EventEntry::Type::CONFIGURATION_CHANGED:
1081 case EventEntry::Type::DEVICE_RESET: {
Chris Yef59a2f42020-10-16 12:55:26 -07001082 LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001083 break;
1084 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001085 }
1086}
1087
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001088static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001089 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1090 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001091}
1092
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001093bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1094 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1095 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1096 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001097}
1098
1099bool InputDispatcher::isAppSwitchPendingLocked() {
1100 return mAppSwitchDueTime != LONG_LONG_MAX;
1101}
1102
1103void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1104 mAppSwitchDueTime = LONG_LONG_MAX;
1105
1106#if DEBUG_APP_SWITCH
1107 if (handled) {
1108 ALOGD("App switch has arrived.");
1109 } else {
1110 ALOGD("App switch was abandoned.");
1111 }
1112#endif
1113}
1114
Michael Wrightd02c5b62014-02-10 15:10:22 -08001115bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001116 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001117}
1118
1119bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001120 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001121 return false;
1122 }
1123
1124 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001125 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001126 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001127 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001128 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001129
1130 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001131 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001132 return true;
1133}
1134
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001135void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1136 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001137}
1138
1139void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001140 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001141 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001142 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001143 releaseInboundEventLocked(entry);
1144 }
1145 traceInboundQueueLengthLocked();
1146}
1147
1148void InputDispatcher::releasePendingEventLocked() {
1149 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001150 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001151 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001152 }
1153}
1154
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001155void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001156 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001157 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001158#if DEBUG_DISPATCH_CYCLE
1159 ALOGD("Injected inbound event was dropped.");
1160#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001161 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001162 }
1163 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001164 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001165 }
1166 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001167}
1168
1169void InputDispatcher::resetKeyRepeatLocked() {
1170 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001171 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001172 }
1173}
1174
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001175std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1176 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001177
Michael Wright2e732952014-09-24 13:26:59 -07001178 uint32_t policyFlags = entry->policyFlags &
1179 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001180
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001181 std::shared_ptr<KeyEntry> newEntry =
1182 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1183 entry->source, entry->displayId, policyFlags, entry->action,
1184 entry->flags, entry->keyCode, entry->scanCode,
1185 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001186
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001187 newEntry->syntheticRepeat = true;
1188 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001189 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001190 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001191}
1192
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001193bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001194 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001195#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001196 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001197#endif
1198
1199 // Reset key repeating in case a keyboard device was added or removed or something.
1200 resetKeyRepeatLocked();
1201
1202 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001203 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1204 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001205 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001206 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001207 return true;
1208}
1209
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001210bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1211 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001212#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001213 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1214 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001215#endif
1216
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001217 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001218 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001219 synthesizeCancelationEventsForAllConnectionsLocked(options);
1220 return true;
1221}
1222
Vishnu Nairad321cd2020-08-20 16:40:21 -07001223void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001224 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001225 if (mPendingEvent != nullptr) {
1226 // Move the pending event to the front of the queue. This will give the chance
1227 // for the pending event to get dispatched to the newly focused window
1228 mInboundQueue.push_front(mPendingEvent);
1229 mPendingEvent = nullptr;
1230 }
1231
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001232 std::unique_ptr<FocusEntry> focusEntry =
1233 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1234 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001235
1236 // This event should go to the front of the queue, but behind all other focus events
1237 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001238 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001239 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001240 [](const std::shared_ptr<EventEntry>& event) {
1241 return event->type == EventEntry::Type::FOCUS;
1242 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001243
1244 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001245 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001246}
1247
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001248void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001249 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001250 if (channel == nullptr) {
1251 return; // Window has gone away
1252 }
1253 InputTarget target;
1254 target.inputChannel = channel;
1255 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1256 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001257 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1258 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001259 std::string reason = std::string("reason=").append(entry->reason);
1260 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001261 dispatchEventLocked(currentTime, entry, {target});
1262}
1263
Prabir Pradhan99987712020-11-10 18:43:05 -08001264void InputDispatcher::dispatchPointerCaptureChangedLocked(
1265 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1266 DropReason& dropReason) {
1267 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan167e6d92021-02-04 16:18:17 -08001268 if (entry->pointerCaptureEnabled && haveWindowWithPointerCapture) {
1269 LOG_ALWAYS_FATAL("Pointer Capture has already been enabled for the window.");
1270 }
1271 if (!entry->pointerCaptureEnabled && !haveWindowWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001272 // Pointer capture was already forcefully disabled because of focus change.
1273 dropReason = DropReason::NOT_DROPPED;
1274 return;
1275 }
1276
1277 // Set drop reason for early returns
1278 dropReason = DropReason::NO_POINTER_CAPTURE;
1279
1280 sp<IBinder> token;
1281 if (entry->pointerCaptureEnabled) {
1282 // Enable Pointer Capture
1283 if (!mFocusedWindowRequestedPointerCapture) {
1284 // This can happen if a window requests capture and immediately releases capture.
1285 ALOGW("No window requested Pointer Capture.");
1286 return;
1287 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08001288 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001289 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1290 mWindowTokenWithPointerCapture = token;
1291 } else {
1292 // Disable Pointer Capture
1293 token = mWindowTokenWithPointerCapture;
1294 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001295 if (mFocusedWindowRequestedPointerCapture) {
1296 mFocusedWindowRequestedPointerCapture = false;
1297 setPointerCaptureLocked(false);
1298 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001299 }
1300
1301 auto channel = getInputChannelLocked(token);
1302 if (channel == nullptr) {
1303 // Window has gone away, clean up Pointer Capture state.
1304 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001305 if (mFocusedWindowRequestedPointerCapture) {
1306 mFocusedWindowRequestedPointerCapture = false;
1307 setPointerCaptureLocked(false);
1308 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001309 return;
1310 }
1311 InputTarget target;
1312 target.inputChannel = channel;
1313 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1314 entry->dispatchInProgress = true;
1315 dispatchEventLocked(currentTime, entry, {target});
1316
1317 dropReason = DropReason::NOT_DROPPED;
1318}
1319
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001320bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001321 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001322 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001323 if (!entry->dispatchInProgress) {
1324 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1325 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1326 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1327 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001328 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001329 // We have seen two identical key downs in a row which indicates that the device
1330 // driver is automatically generating key repeats itself. We take note of the
1331 // repeat here, but we disable our own next key repeat timer since it is clear that
1332 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001333 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1334 // Make sure we don't get key down from a different device. If a different
1335 // device Id has same key pressed down, the new device Id will replace the
1336 // current one to hold the key repeat with repeat count reset.
1337 // In the future when got a KEY_UP on the device id, drop it and do not
1338 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001339 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1340 resetKeyRepeatLocked();
1341 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1342 } else {
1343 // Not a repeat. Save key down state in case we do see a repeat later.
1344 resetKeyRepeatLocked();
1345 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1346 }
1347 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001348 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1349 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001350 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001351#if DEBUG_INBOUND_EVENT_DETAILS
1352 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1353#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001354 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001355 resetKeyRepeatLocked();
1356 }
1357
1358 if (entry->repeatCount == 1) {
1359 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1360 } else {
1361 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1362 }
1363
1364 entry->dispatchInProgress = true;
1365
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001366 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001367 }
1368
1369 // Handle case where the policy asked us to try again later last time.
1370 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1371 if (currentTime < entry->interceptKeyWakeupTime) {
1372 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1373 *nextWakeupTime = entry->interceptKeyWakeupTime;
1374 }
1375 return false; // wait until next wakeup
1376 }
1377 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1378 entry->interceptKeyWakeupTime = 0;
1379 }
1380
1381 // Give the policy a chance to intercept the key.
1382 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1383 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001384 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001385 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001386 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001387 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001388 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001389 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001390 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001391 return false; // wait for the command to run
1392 } else {
1393 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1394 }
1395 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001396 if (*dropReason == DropReason::NOT_DROPPED) {
1397 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001398 }
1399 }
1400
1401 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001402 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001403 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001404 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1405 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001406 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001407 return true;
1408 }
1409
1410 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001411 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001412 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001413 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001414 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001415 return false;
1416 }
1417
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001418 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001419 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001420 return true;
1421 }
1422
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001423 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001424 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001425
1426 // Dispatch the key.
1427 dispatchEventLocked(currentTime, entry, inputTargets);
1428 return true;
1429}
1430
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001431void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001432#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001433 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001434 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1435 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001436 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1437 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1438 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001439#endif
1440}
1441
Chris Yef59a2f42020-10-16 12:55:26 -07001442void InputDispatcher::doNotifySensorLockedInterruptible(CommandEntry* commandEntry) {
1443 mLock.unlock();
1444
1445 const std::shared_ptr<SensorEntry>& entry = commandEntry->sensorEntry;
1446 if (entry->accuracyChanged) {
1447 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1448 }
1449 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1450 entry->hwTimestamp, entry->values);
1451 mLock.lock();
1452}
1453
1454void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, std::shared_ptr<SensorEntry> entry,
1455 DropReason* dropReason, nsecs_t* nextWakeupTime) {
1456#if DEBUG_OUTBOUND_EVENT_DETAILS
1457 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1458 "source=0x%x, sensorType=%s",
1459 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Prabir Pradhanbe05b5b2021-02-24 16:39:43 -08001460 NamedEnum::string(entry->sensorType).c_str());
Chris Yef59a2f42020-10-16 12:55:26 -07001461#endif
1462 std::unique_ptr<CommandEntry> commandEntry =
1463 std::make_unique<CommandEntry>(&InputDispatcher::doNotifySensorLockedInterruptible);
1464 commandEntry->sensorEntry = entry;
1465 postCommandLocked(std::move(commandEntry));
1466}
1467
1468bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
1469#if DEBUG_OUTBOUND_EVENT_DETAILS
1470 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
1471 NamedEnum::string(sensorType).c_str());
1472#endif
1473 { // acquire lock
1474 std::scoped_lock _l(mLock);
1475
1476 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1477 std::shared_ptr<EventEntry> entry = *it;
1478 if (entry->type == EventEntry::Type::SENSOR) {
1479 it = mInboundQueue.erase(it);
1480 releaseInboundEventLocked(entry);
1481 }
1482 }
1483 }
1484 return true;
1485}
1486
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001487bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001488 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001489 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001490 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001491 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001492 entry->dispatchInProgress = true;
1493
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001494 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001495 }
1496
1497 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001498 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001499 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001500 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1501 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001502 return true;
1503 }
1504
1505 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1506
1507 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001508 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001509
1510 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001511 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001512 if (isPointerEvent) {
1513 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001514 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001515 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001516 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001517 } else {
1518 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001519 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001520 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001521 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001522 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001523 return false;
1524 }
1525
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001526 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001527 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001528 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1529 return true;
1530 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001531 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001532 CancelationOptions::Mode mode(isPointerEvent
1533 ? CancelationOptions::CANCEL_POINTER_EVENTS
1534 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1535 CancelationOptions options(mode, "input event injection failed");
1536 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001537 return true;
1538 }
1539
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001540 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001541 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001542
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001543 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001544 std::unordered_map<int32_t, TouchState>::iterator it =
1545 mTouchStatesByDisplay.find(entry->displayId);
1546 if (it != mTouchStatesByDisplay.end()) {
1547 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001548 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001549 // The event has gone through these portal windows, so we add monitoring targets of
1550 // the corresponding displays as well.
1551 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001552 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001553 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001554 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001555 }
1556 }
1557 }
1558 }
1559
Michael Wrightd02c5b62014-02-10 15:10:22 -08001560 // Dispatch the motion.
1561 if (conflictingPointerActions) {
1562 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001563 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001564 synthesizeCancelationEventsForAllConnectionsLocked(options);
1565 }
1566 dispatchEventLocked(currentTime, entry, inputTargets);
1567 return true;
1568}
1569
arthurhungb89ccb02020-12-30 16:19:01 +08001570void InputDispatcher::enqueueDragEventLocked(const sp<InputWindowHandle>& windowHandle,
1571 bool isExiting, const MotionEntry& motionEntry) {
1572 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1573 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1574 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1575 PointerCoords pointerCoords;
1576 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1577 pointerCoords.transform(windowHandle->getInfo()->transform);
1578
1579 std::unique_ptr<DragEntry> dragEntry =
1580 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1581 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1582 pointerCoords.getY());
1583
1584 enqueueInboundEventLocked(std::move(dragEntry));
1585}
1586
1587void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1588 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1589 if (channel == nullptr) {
1590 return; // Window has gone away
1591 }
1592 InputTarget target;
1593 target.inputChannel = channel;
1594 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1595 entry->dispatchInProgress = true;
1596 dispatchEventLocked(currentTime, entry, {target});
1597}
1598
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001599void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001600#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001601 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001602 ", policyFlags=0x%x, "
1603 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1604 "metaState=0x%x, buttonState=0x%x,"
1605 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001606 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1607 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1608 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001609
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001610 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001611 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001612 "x=%f, y=%f, pressure=%f, size=%f, "
1613 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1614 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001615 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1616 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1617 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1618 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1619 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1620 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1621 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1622 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1623 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1624 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001625 }
1626#endif
1627}
1628
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001629void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1630 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001631 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001632 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001633#if DEBUG_DISPATCH_CYCLE
1634 ALOGD("dispatchEventToCurrentInputTargets");
1635#endif
1636
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001637 updateInteractionTokensLocked(*eventEntry, inputTargets);
1638
Michael Wrightd02c5b62014-02-10 15:10:22 -08001639 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1640
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001641 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001642
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001643 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001644 sp<Connection> connection =
1645 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001646 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001647 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001648 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001649 if (DEBUG_FOCUS) {
1650 ALOGD("Dropping event delivery to target with channel '%s' because it "
1651 "is no longer registered with the input dispatcher.",
1652 inputTarget.inputChannel->getName().c_str());
1653 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001654 }
1655 }
1656}
1657
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001658void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1659 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1660 // If the policy decides to close the app, we will get a channel removal event via
1661 // unregisterInputChannel, and will clean up the connection that way. We are already not
1662 // sending new pointers to the connection when it blocked, but focused events will continue to
1663 // pile up.
1664 ALOGW("Canceling events for %s because it is unresponsive",
1665 connection->inputChannel->getName().c_str());
1666 if (connection->status == Connection::STATUS_NORMAL) {
1667 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1668 "application not responding");
1669 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001670 }
1671}
1672
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001673void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001674 if (DEBUG_FOCUS) {
1675 ALOGD("Resetting ANR timeouts.");
1676 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001677
1678 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001679 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001680 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001681}
1682
Tiger Huang721e26f2018-07-24 22:26:19 +08001683/**
1684 * Get the display id that the given event should go to. If this event specifies a valid display id,
1685 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1686 * Focused display is the display that the user most recently interacted with.
1687 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001688int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001689 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001690 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001691 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001692 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1693 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001694 break;
1695 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001696 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001697 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1698 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001699 break;
1700 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001701 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001702 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001703 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001704 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001705 case EventEntry::Type::SENSOR:
1706 case EventEntry::Type::DRAG: {
Chris Yef59a2f42020-10-16 12:55:26 -07001707 ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001708 return ADISPLAY_ID_NONE;
1709 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001710 }
1711 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1712}
1713
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001714bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1715 const char* focusedWindowName) {
1716 if (mAnrTracker.empty()) {
1717 // already processed all events that we waited for
1718 mKeyIsWaitingForEventsTimeout = std::nullopt;
1719 return false;
1720 }
1721
1722 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1723 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001724 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001725 mKeyIsWaitingForEventsTimeout = currentTime +
1726 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1727 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001728 return true;
1729 }
1730
1731 // We still have pending events, and already started the timer
1732 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1733 return true; // Still waiting
1734 }
1735
1736 // Waited too long, and some connection still hasn't processed all motions
1737 // Just send the key to the focused window
1738 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1739 focusedWindowName);
1740 mKeyIsWaitingForEventsTimeout = std::nullopt;
1741 return false;
1742}
1743
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001744InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1745 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1746 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001747 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001748
Tiger Huang721e26f2018-07-24 22:26:19 +08001749 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001750 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001751 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001752 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1753
Michael Wrightd02c5b62014-02-10 15:10:22 -08001754 // If there is no currently focused window and no focused application
1755 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001756 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1757 ALOGI("Dropping %s event because there is no focused window or focused application in "
1758 "display %" PRId32 ".",
Chris Yef59a2f42020-10-16 12:55:26 -07001759 NamedEnum::string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001760 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001761 }
1762
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001763 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1764 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1765 // start interacting with another application via touch (app switch). This code can be removed
1766 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1767 // an app is expected to have a focused window.
1768 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1769 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1770 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001771 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1772 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1773 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001774 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001775 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001776 ALOGW("Waiting because no window has focus but %s may eventually add a "
1777 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001778 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001779 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001780 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001781 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1782 // Already raised ANR. Drop the event
1783 ALOGE("Dropping %s event because there is no focused window",
Chris Yef59a2f42020-10-16 12:55:26 -07001784 NamedEnum::string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001785 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001786 } else {
1787 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001788 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001789 }
1790 }
1791
1792 // we have a valid, non-null focused window
1793 resetNoFocusedWindowTimeoutLocked();
1794
Michael Wrightd02c5b62014-02-10 15:10:22 -08001795 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001796 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001797 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001798 }
1799
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001800 if (focusedWindowHandle->getInfo()->paused) {
1801 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001802 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001803 }
1804
1805 // If the event is a key event, then we must wait for all previous events to
1806 // complete before delivering it because previous events may have the
1807 // side-effect of transferring focus to a different window and we want to
1808 // ensure that the following keys are sent to the new window.
1809 //
1810 // Suppose the user touches a button in a window then immediately presses "A".
1811 // If the button causes a pop-up window to appear then we want to ensure that
1812 // the "A" key is delivered to the new pop-up window. This is because users
1813 // often anticipate pending UI changes when typing on a keyboard.
1814 // To obtain this behavior, we must serialize key events with respect to all
1815 // prior input events.
1816 if (entry.type == EventEntry::Type::KEY) {
1817 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1818 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001819 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001820 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001821 }
1822
1823 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001824 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001825 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1826 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001827
1828 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001829 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001830}
1831
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001832/**
1833 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1834 * that are currently unresponsive.
1835 */
1836std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1837 const std::vector<TouchedMonitor>& monitors) const {
1838 std::vector<TouchedMonitor> responsiveMonitors;
1839 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1840 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1841 sp<Connection> connection = getConnectionLocked(
1842 monitor.monitor.inputChannel->getConnectionToken());
1843 if (connection == nullptr) {
1844 ALOGE("Could not find connection for monitor %s",
1845 monitor.monitor.inputChannel->getName().c_str());
1846 return false;
1847 }
1848 if (!connection->responsive) {
1849 ALOGW("Unresponsive monitor %s will not get the new gesture",
1850 connection->inputChannel->getName().c_str());
1851 return false;
1852 }
1853 return true;
1854 });
1855 return responsiveMonitors;
1856}
1857
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001858InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1859 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1860 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001861 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001862 enum InjectionPermission {
1863 INJECTION_PERMISSION_UNKNOWN,
1864 INJECTION_PERMISSION_GRANTED,
1865 INJECTION_PERMISSION_DENIED
1866 };
1867
Michael Wrightd02c5b62014-02-10 15:10:22 -08001868 // For security reasons, we defer updating the touch state until we are sure that
1869 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001870 int32_t displayId = entry.displayId;
1871 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001872 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1873
1874 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001875 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001876 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001877 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1878 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001879
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001880 // Copy current touch state into tempTouchState.
1881 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1882 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001883 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001884 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001885 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1886 mTouchStatesByDisplay.find(displayId);
1887 if (oldStateIt != mTouchStatesByDisplay.end()) {
1888 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001889 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001890 }
1891
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001892 bool isSplit = tempTouchState.split;
1893 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1894 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1895 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001896 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1897 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1898 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1899 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1900 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001901 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001902 bool wrongDevice = false;
1903 if (newGesture) {
1904 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001905 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001906 ALOGI("Dropping event because a pointer for a different device is already down "
1907 "in display %" PRId32,
1908 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001909 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001910 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001911 switchedDevice = false;
1912 wrongDevice = true;
1913 goto Failed;
1914 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001915 tempTouchState.reset();
1916 tempTouchState.down = down;
1917 tempTouchState.deviceId = entry.deviceId;
1918 tempTouchState.source = entry.source;
1919 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001921 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001922 ALOGI("Dropping move event because a pointer for a different device is already active "
1923 "in display %" PRId32,
1924 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001925 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001926 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001927 switchedDevice = false;
1928 wrongDevice = true;
1929 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001930 }
1931
1932 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1933 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1934
Garfield Tan00f511d2019-06-12 16:55:40 -07001935 int32_t x;
1936 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001937 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001938 // Always dispatch mouse events to cursor position.
1939 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001940 x = int32_t(entry.xCursorPosition);
1941 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001942 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001943 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1944 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001945 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001946 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001947 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001948 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1949 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001950
1951 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001952 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001953 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001954
Michael Wrightd02c5b62014-02-10 15:10:22 -08001955 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001956 if (newTouchedWindowHandle != nullptr &&
1957 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001958 // New window supports splitting, but we should never split mouse events.
1959 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001960 } else if (isSplit) {
1961 // New window does not support splitting but we have already split events.
1962 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001963 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001964 }
1965
1966 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001967 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001968 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001969 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001970 }
1971
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001972 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1973 ALOGI("Not sending touch event to %s because it is paused",
1974 newTouchedWindowHandle->getName().c_str());
1975 newTouchedWindowHandle = nullptr;
1976 }
1977
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001978 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001979 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001980 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1981 if (!isResponsive) {
1982 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001983 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1984 newTouchedWindowHandle = nullptr;
1985 }
1986 }
1987
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001988 // Drop events that can't be trusted due to occlusion
1989 if (newTouchedWindowHandle != nullptr &&
1990 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1991 TouchOcclusionInfo occlusionInfo =
1992 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001993 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001994 if (DEBUG_TOUCH_OCCLUSION) {
1995 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1996 for (const auto& log : occlusionInfo.debugInfo) {
1997 ALOGD("%s", log.c_str());
1998 }
1999 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002000 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
2001 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2002 ALOGW("Dropping untrusted touch event due to %s/%d",
2003 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2004 newTouchedWindowHandle = nullptr;
2005 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002006 }
2007 }
2008
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002009 // Also don't send the new touch event to unresponsive gesture monitors
2010 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
2011
Michael Wright3dd60e22019-03-27 22:06:44 +00002012 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
2013 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002014 "(%d, %d) in display %" PRId32 ".",
2015 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002016 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00002017 goto Failed;
2018 }
2019
2020 if (newTouchedWindowHandle != nullptr) {
2021 // Set target flags.
2022 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
2023 if (isSplit) {
2024 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002025 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002026 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2027 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2028 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2029 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2030 }
2031
2032 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07002033 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2034 newHoverWindowHandle = nullptr;
2035 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002036 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002037 }
2038
2039 // Update the temporary touch state.
2040 BitSet32 pointerIds;
2041 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002042 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002043 pointerIds.markBit(pointerId);
2044 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002045 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002046 }
2047
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002048 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002049 } else {
2050 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2051
2052 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002053 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002054 if (DEBUG_FOCUS) {
2055 ALOGD("Dropping event because the pointer is not down or we previously "
2056 "dropped the pointer down event in display %" PRId32,
2057 displayId);
2058 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002059 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002060 goto Failed;
2061 }
2062
arthurhungb89ccb02020-12-30 16:19:01 +08002063 addDragEventLocked(entry, tempTouchState);
2064
Michael Wrightd02c5b62014-02-10 15:10:22 -08002065 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002066 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002067 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002068 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2069 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002070
2071 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002072 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002073 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002074 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2075 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002076 if (DEBUG_FOCUS) {
2077 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2078 oldTouchedWindowHandle->getName().c_str(),
2079 newTouchedWindowHandle->getName().c_str(), displayId);
2080 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002081 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002082 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2083 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2084 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002085
2086 // Make a slippery entrance into the new window.
2087 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2088 isSplit = true;
2089 }
2090
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002091 int32_t targetFlags =
2092 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002093 if (isSplit) {
2094 targetFlags |= InputTarget::FLAG_SPLIT;
2095 }
2096 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2097 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002098 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2099 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002100 }
2101
2102 BitSet32 pointerIds;
2103 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002104 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002105 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002106 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002107 }
2108 }
2109 }
2110
2111 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002112 // Let the previous window know that the hover sequence is over, unless we already did it
2113 // when dispatching it as is to newTouchedWindowHandle.
2114 if (mLastHoverWindowHandle != nullptr &&
2115 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2116 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002117#if DEBUG_HOVER
2118 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002119 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002120#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002121 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2122 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002123 }
2124
Garfield Tandf26e862020-07-01 20:18:19 -07002125 // Let the new window know that the hover sequence is starting, unless we already did it
2126 // when dispatching it as is to newTouchedWindowHandle.
2127 if (newHoverWindowHandle != nullptr &&
2128 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2129 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002130#if DEBUG_HOVER
2131 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002132 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002133#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002134 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2135 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2136 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002137 }
2138 }
2139
2140 // Check permission to inject into all touched foreground windows and ensure there
2141 // is at least one touched foreground window.
2142 {
2143 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002144 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002145 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2146 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002147 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002148 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002149 injectionPermission = INJECTION_PERMISSION_DENIED;
2150 goto Failed;
2151 }
2152 }
2153 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002154 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002155 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002156 ALOGI("Dropping event because there is no touched foreground window in display "
2157 "%" PRId32 " or gesture monitor to receive it.",
2158 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002159 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002160 goto Failed;
2161 }
2162
2163 // Permission granted to injection into all touched foreground windows.
2164 injectionPermission = INJECTION_PERMISSION_GRANTED;
2165 }
2166
2167 // Check whether windows listening for outside touches are owned by the same UID. If it is
2168 // set the policy flag that we will not reveal coordinate information to this window.
2169 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2170 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002171 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002172 if (foregroundWindowHandle) {
2173 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002174 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002175 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2176 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
2177 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002178 tempTouchState.addOrUpdateWindow(inputWindowHandle,
2179 InputTarget::FLAG_ZERO_COORDS,
2180 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002181 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002182 }
2183 }
2184 }
2185 }
2186
Michael Wrightd02c5b62014-02-10 15:10:22 -08002187 // If this is the first pointer going down and the touched window has a wallpaper
2188 // then also add the touched wallpaper windows so they are locked in for the duration
2189 // of the touch gesture.
2190 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2191 // engine only supports touch events. We would need to add a mechanism similar
2192 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2193 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2194 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002195 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002196 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07002197 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002198 getWindowHandlesLocked(displayId);
2199 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002200 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002201 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01002202 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002203 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002204 .addOrUpdateWindow(windowHandle,
2205 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2206 InputTarget::
2207 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2208 InputTarget::FLAG_DISPATCH_AS_IS,
2209 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002210 }
2211 }
2212 }
2213 }
2214
2215 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002216 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002217
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002218 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002219 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002220 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002221 }
2222
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002223 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002224 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002225 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002226 }
2227
Michael Wrightd02c5b62014-02-10 15:10:22 -08002228 // Drop the outside or hover touch windows since we will not care about them
2229 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002230 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002231
2232Failed:
2233 // Check injection permission once and for all.
2234 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002235 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002236 injectionPermission = INJECTION_PERMISSION_GRANTED;
2237 } else {
2238 injectionPermission = INJECTION_PERMISSION_DENIED;
2239 }
2240 }
2241
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002242 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2243 return injectionResult;
2244 }
2245
Michael Wrightd02c5b62014-02-10 15:10:22 -08002246 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002247 if (!wrongDevice) {
2248 if (switchedDevice) {
2249 if (DEBUG_FOCUS) {
2250 ALOGD("Conflicting pointer actions: Switched to a different device.");
2251 }
2252 *outConflictingPointerActions = true;
2253 }
2254
2255 if (isHoverAction) {
2256 // Started hovering, therefore no longer down.
2257 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002258 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002259 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2260 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002261 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002262 *outConflictingPointerActions = true;
2263 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002264 tempTouchState.reset();
2265 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2266 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2267 tempTouchState.deviceId = entry.deviceId;
2268 tempTouchState.source = entry.source;
2269 tempTouchState.displayId = displayId;
2270 }
2271 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2272 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2273 // All pointers up or canceled.
2274 tempTouchState.reset();
2275 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2276 // First pointer went down.
2277 if (oldState && oldState->down) {
2278 if (DEBUG_FOCUS) {
2279 ALOGD("Conflicting pointer actions: Down received while already down.");
2280 }
2281 *outConflictingPointerActions = true;
2282 }
2283 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2284 // One pointer went up.
2285 if (isSplit) {
2286 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2287 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002288
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002289 for (size_t i = 0; i < tempTouchState.windows.size();) {
2290 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2291 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2292 touchedWindow.pointerIds.clearBit(pointerId);
2293 if (touchedWindow.pointerIds.isEmpty()) {
2294 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2295 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002296 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002297 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002298 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002299 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002300 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002301 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002302
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002303 // Save changes unless the action was scroll in which case the temporary touch
2304 // state was only valid for this one action.
2305 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2306 if (tempTouchState.displayId >= 0) {
2307 mTouchStatesByDisplay[displayId] = tempTouchState;
2308 } else {
2309 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002310 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002311 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002312
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002313 // Update hover state.
2314 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002315 }
2316
Michael Wrightd02c5b62014-02-10 15:10:22 -08002317 return injectionResult;
2318}
2319
arthurhungb89ccb02020-12-30 16:19:01 +08002320void InputDispatcher::addDragEventLocked(const MotionEntry& entry, TouchState& state) {
2321 if (entry.pointerCount != 1 || !state.dragWindow) {
2322 return;
2323 }
2324
2325 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2326 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2327 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2328 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
2329 const sp<InputWindowHandle> hoverWindowHandle =
2330 findTouchedWindowAtLocked(entry.displayId, x, y, &state,
2331 false /*addOutsideTargets*/, false /*addPortalWindows*/,
2332 true /*ignoreDragWindow*/);
2333 // enqueue drag exit if needed.
2334 if (hoverWindowHandle != state.dragHoverWindowHandle &&
2335 !haveSameToken(hoverWindowHandle, state.dragHoverWindowHandle)) {
2336 if (state.dragHoverWindowHandle != nullptr) {
2337 enqueueDragEventLocked(state.dragHoverWindowHandle, true /*isExiting*/, entry);
2338 }
2339 state.dragHoverWindowHandle = hoverWindowHandle;
2340 }
2341 // enqueue drag location if needed.
2342 if (hoverWindowHandle != nullptr) {
2343 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2344 }
2345 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2346 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2347 state.dragWindow = nullptr;
2348 state.dragHoverWindowHandle = nullptr;
2349 }
2350}
2351
Michael Wrightd02c5b62014-02-10 15:10:22 -08002352void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002353 int32_t targetFlags, BitSet32 pointerIds,
2354 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002355 std::vector<InputTarget>::iterator it =
2356 std::find_if(inputTargets.begin(), inputTargets.end(),
2357 [&windowHandle](const InputTarget& inputTarget) {
2358 return inputTarget.inputChannel->getConnectionToken() ==
2359 windowHandle->getToken();
2360 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002361
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002362 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002363
2364 if (it == inputTargets.end()) {
2365 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002366 std::shared_ptr<InputChannel> inputChannel =
2367 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002368 if (inputChannel == nullptr) {
2369 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2370 return;
2371 }
2372 inputTarget.inputChannel = inputChannel;
2373 inputTarget.flags = targetFlags;
2374 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2375 inputTargets.push_back(inputTarget);
2376 it = inputTargets.end() - 1;
2377 }
2378
2379 ALOG_ASSERT(it->flags == targetFlags);
2380 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2381
chaviw1ff3d1e2020-07-01 15:53:47 -07002382 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002383}
2384
Michael Wright3dd60e22019-03-27 22:06:44 +00002385void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002386 int32_t displayId, float xOffset,
2387 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002388 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2389 mGlobalMonitorsByDisplay.find(displayId);
2390
2391 if (it != mGlobalMonitorsByDisplay.end()) {
2392 const std::vector<Monitor>& monitors = it->second;
2393 for (const Monitor& monitor : monitors) {
2394 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002395 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002396 }
2397}
2398
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002399void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2400 float yOffset,
2401 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002402 InputTarget target;
2403 target.inputChannel = monitor.inputChannel;
2404 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002405 ui::Transform t;
2406 t.set(xOffset, yOffset);
2407 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002408 inputTargets.push_back(target);
2409}
2410
Michael Wrightd02c5b62014-02-10 15:10:22 -08002411bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002412 const InjectionState* injectionState) {
2413 if (injectionState &&
2414 (windowHandle == nullptr ||
2415 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2416 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002417 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002418 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002419 "owned by uid %d",
2420 injectionState->injectorPid, injectionState->injectorUid,
2421 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002422 } else {
2423 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002424 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002425 }
2426 return false;
2427 }
2428 return true;
2429}
2430
Robert Carrc9bf1d32020-04-13 17:21:08 -07002431/**
2432 * Indicate whether one window handle should be considered as obscuring
2433 * another window handle. We only check a few preconditions. Actually
2434 * checking the bounds is left to the caller.
2435 */
2436static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2437 const sp<InputWindowHandle>& otherHandle) {
2438 // Compare by token so cloned layers aren't counted
2439 if (haveSameToken(windowHandle, otherHandle)) {
2440 return false;
2441 }
2442 auto info = windowHandle->getInfo();
2443 auto otherInfo = otherHandle->getInfo();
2444 if (!otherInfo->visible) {
2445 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002446 } else if (otherInfo->alpha == 0 &&
2447 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2448 // Those act as if they were invisible, so we don't need to flag them.
2449 // We do want to potentially flag touchable windows even if they have 0
2450 // opacity, since they can consume touches and alter the effects of the
2451 // user interaction (eg. apps that rely on
2452 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2453 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2454 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002455 } else if (info->ownerUid == otherInfo->ownerUid) {
2456 // If ownerUid is the same we don't generate occlusion events as there
2457 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002458 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002459 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002460 return false;
2461 } else if (otherInfo->displayId != info->displayId) {
2462 return false;
2463 }
2464 return true;
2465}
2466
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002467/**
2468 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2469 * untrusted, one should check:
2470 *
2471 * 1. If result.hasBlockingOcclusion is true.
2472 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2473 * BLOCK_UNTRUSTED.
2474 *
2475 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2476 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2477 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2478 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2479 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2480 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2481 *
2482 * If neither of those is true, then it means the touch can be allowed.
2483 */
2484InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2485 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002486 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2487 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002488 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2489 TouchOcclusionInfo info;
2490 info.hasBlockingOcclusion = false;
2491 info.obscuringOpacity = 0;
2492 info.obscuringUid = -1;
2493 std::map<int32_t, float> opacityByUid;
2494 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2495 if (windowHandle == otherHandle) {
2496 break; // All future windows are below us. Exit early.
2497 }
2498 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002499 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2500 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002501 if (DEBUG_TOUCH_OCCLUSION) {
2502 info.debugInfo.push_back(
2503 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2504 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002505 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2506 // we perform the checks below to see if the touch can be propagated or not based on the
2507 // window's touch occlusion mode
2508 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2509 info.hasBlockingOcclusion = true;
2510 info.obscuringUid = otherInfo->ownerUid;
2511 info.obscuringPackage = otherInfo->packageName;
2512 break;
2513 }
2514 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2515 uint32_t uid = otherInfo->ownerUid;
2516 float opacity =
2517 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2518 // Given windows A and B:
2519 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2520 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2521 opacityByUid[uid] = opacity;
2522 if (opacity > info.obscuringOpacity) {
2523 info.obscuringOpacity = opacity;
2524 info.obscuringUid = uid;
2525 info.obscuringPackage = otherInfo->packageName;
2526 }
2527 }
2528 }
2529 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002530 if (DEBUG_TOUCH_OCCLUSION) {
2531 info.debugInfo.push_back(
2532 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2533 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002534 return info;
2535}
2536
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002537std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2538 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002539 return StringPrintf(INDENT2
2540 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2541 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2542 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2543 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002544 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002545 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002546 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002547 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2548 info->frameTop, info->frameRight, info->frameBottom,
2549 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002550 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2551 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2552 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002553}
2554
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002555bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2556 if (occlusionInfo.hasBlockingOcclusion) {
2557 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2558 occlusionInfo.obscuringUid);
2559 return false;
2560 }
2561 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2562 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2563 "%.2f, maximum allowed = %.2f)",
2564 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2565 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2566 return false;
2567 }
2568 return true;
2569}
2570
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002571bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2572 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002573 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002574 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002575 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002576 if (windowHandle == otherHandle) {
2577 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002578 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002579 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002580 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002581 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002582 return true;
2583 }
2584 }
2585 return false;
2586}
2587
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002588bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2589 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002590 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002591 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002592 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002593 if (windowHandle == otherHandle) {
2594 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002595 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002596 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002597 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002598 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002599 return true;
2600 }
2601 }
2602 return false;
2603}
2604
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002605std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002606 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002607 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002608 if (applicationHandle != nullptr) {
2609 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002610 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002611 } else {
2612 return applicationHandle->getName();
2613 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002614 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002615 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002616 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002617 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002618 }
2619}
2620
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002621void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002622 if (eventEntry.type == EventEntry::Type::FOCUS ||
arthurhungb89ccb02020-12-30 16:19:01 +08002623 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED ||
2624 eventEntry.type == EventEntry::Type::DRAG) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002625 // Focus or pointer capture changed events are passed to apps, but do not represent user
2626 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002627 return;
2628 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002629 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002630 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002631 if (focusedWindowHandle != nullptr) {
2632 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002633 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002634#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002635 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002636#endif
2637 return;
2638 }
2639 }
2640
2641 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002642 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002643 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002644 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2645 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002646 return;
2647 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002648
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002649 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002650 eventType = USER_ACTIVITY_EVENT_TOUCH;
2651 }
2652 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002653 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002654 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002655 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2656 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002657 return;
2658 }
2659 eventType = USER_ACTIVITY_EVENT_BUTTON;
2660 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002661 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002662 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002663 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002664 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002665 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08002666 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2667 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002668 LOG_ALWAYS_FATAL("%s events are not user activity",
Chris Yef59a2f42020-10-16 12:55:26 -07002669 NamedEnum::string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002670 break;
2671 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002672 }
2673
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002674 std::unique_ptr<CommandEntry> commandEntry =
2675 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002676 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002677 commandEntry->userActivityEventType = eventType;
Sean Stoutb4e0a592021-02-23 07:34:53 -08002678 commandEntry->displayId = displayId;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002679 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002680}
2681
2682void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002683 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002684 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002685 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002686 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002687 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002688 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002689 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002690 ATRACE_NAME(message.c_str());
2691 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002692#if DEBUG_DISPATCH_CYCLE
2693 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002694 "globalScaleFactor=%f, pointerIds=0x%x %s",
2695 connection->getInputChannelName().c_str(), inputTarget.flags,
2696 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2697 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002698#endif
2699
2700 // Skip this event if the connection status is not normal.
2701 // We don't want to enqueue additional outbound events if the connection is broken.
2702 if (connection->status != Connection::STATUS_NORMAL) {
2703#if DEBUG_DISPATCH_CYCLE
2704 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002705 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002706#endif
2707 return;
2708 }
2709
2710 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002711 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2712 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2713 "Entry type %s should not have FLAG_SPLIT",
Chris Yef59a2f42020-10-16 12:55:26 -07002714 NamedEnum::string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002715
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002716 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002717 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002718 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002719 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002720 if (!splitMotionEntry) {
2721 return; // split event was dropped
2722 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002723 if (DEBUG_FOCUS) {
2724 ALOGD("channel '%s' ~ Split motion event.",
2725 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002726 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002727 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002728 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2729 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002730 return;
2731 }
2732 }
2733
2734 // Not splitting. Enqueue dispatch entries for the event as is.
2735 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2736}
2737
2738void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002739 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002740 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002741 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002742 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002743 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002744 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002745 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002746 ATRACE_NAME(message.c_str());
2747 }
2748
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002749 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002750
2751 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002752 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002753 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002754 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002755 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002756 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002757 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002758 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002759 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002760 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002761 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002762 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002763 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002764
2765 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002766 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002767 startDispatchCycleLocked(currentTime, connection);
2768 }
2769}
2770
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002771void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002772 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002773 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002774 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002775 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002776 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2777 connection->getInputChannelName().c_str(),
2778 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002779 ATRACE_NAME(message.c_str());
2780 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002781 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002782 if (!(inputTargetFlags & dispatchMode)) {
2783 return;
2784 }
2785 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2786
2787 // This is a new event.
2788 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002789 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002790 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002791
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002792 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2793 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002794 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002795 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002796 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002797 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002798 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002799 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002800 dispatchEntry->resolvedAction = keyEntry.action;
2801 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002802
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002803 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2804 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002805#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002806 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2807 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002808#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002809 return; // skip the inconsistent event
2810 }
2811 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002812 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002813
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002814 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002815 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002816 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2817 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2818 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2819 static_cast<int32_t>(IdGenerator::Source::OTHER);
2820 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002821 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2822 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2823 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2824 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2825 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2826 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2827 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2828 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2829 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2830 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2831 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002832 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002833 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002834 }
2835 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002836 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2837 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002838#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002839 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2840 "event",
2841 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002842#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002843 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2844 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002845
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002846 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002847 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2848 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2849 }
2850 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2851 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2852 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002853
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002854 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2855 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002856#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002857 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2858 "event",
2859 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002860#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002861 return; // skip the inconsistent event
2862 }
2863
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002864 dispatchEntry->resolvedEventId =
2865 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2866 ? mIdGenerator.nextId()
2867 : motionEntry.id;
2868 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2869 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2870 ") to MotionEvent(id=0x%" PRIx32 ").",
2871 motionEntry.id, dispatchEntry->resolvedEventId);
2872 ATRACE_NAME(message.c_str());
2873 }
2874
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002875 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002876 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002877
2878 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002879 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002880 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08002881 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2882 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002883 break;
2884 }
Chris Yef59a2f42020-10-16 12:55:26 -07002885 case EventEntry::Type::SENSOR: {
2886 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
2887 break;
2888 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002889 case EventEntry::Type::CONFIGURATION_CHANGED:
2890 case EventEntry::Type::DEVICE_RESET: {
2891 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chris Yef59a2f42020-10-16 12:55:26 -07002892 NamedEnum::string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002893 break;
2894 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002895 }
2896
2897 // Remember that we are waiting for this dispatch to complete.
2898 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002899 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002900 }
2901
2902 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002903 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002904 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002905}
2906
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002907/**
2908 * This function is purely for debugging. It helps us understand where the user interaction
2909 * was taking place. For example, if user is touching launcher, we will see a log that user
2910 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2911 * We will see both launcher and wallpaper in that list.
2912 * Once the interaction with a particular set of connections starts, no new logs will be printed
2913 * until the set of interacted connections changes.
2914 *
2915 * The following items are skipped, to reduce the logspam:
2916 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2917 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2918 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2919 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2920 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002921 */
2922void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2923 const std::vector<InputTarget>& targets) {
2924 // Skip ACTION_UP events, and all events other than keys and motions
2925 if (entry.type == EventEntry::Type::KEY) {
2926 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2927 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2928 return;
2929 }
2930 } else if (entry.type == EventEntry::Type::MOTION) {
2931 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2932 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2933 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2934 return;
2935 }
2936 } else {
2937 return; // Not a key or a motion
2938 }
2939
2940 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2941 std::vector<sp<Connection>> newConnections;
2942 for (const InputTarget& target : targets) {
2943 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2944 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2945 continue; // Skip windows that receive ACTION_OUTSIDE
2946 }
2947
2948 sp<IBinder> token = target.inputChannel->getConnectionToken();
2949 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002950 if (connection == nullptr) {
2951 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002952 }
2953 newConnectionTokens.insert(std::move(token));
2954 newConnections.emplace_back(connection);
2955 }
2956 if (newConnectionTokens == mInteractionConnectionTokens) {
2957 return; // no change
2958 }
2959 mInteractionConnectionTokens = newConnectionTokens;
2960
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002961 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002962 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002963 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002964 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002965 std::string message = "Interaction with: " + targetList;
2966 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002967 message += "<none>";
2968 }
2969 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2970}
2971
chaviwfd6d3512019-03-25 13:23:49 -07002972void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002973 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002974 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002975 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2976 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002977 return;
2978 }
2979
Vishnu Nairc519ff72021-01-21 08:23:08 -08002980 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002981 if (focusedToken == token) {
2982 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002983 return;
2984 }
2985
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002986 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2987 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002988 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002989 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002990}
2991
2992void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002993 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002994 if (ATRACE_ENABLED()) {
2995 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002996 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002997 ATRACE_NAME(message.c_str());
2998 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002999#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003000 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003001#endif
3002
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003003 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3004 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003005 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003006 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003007 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003008 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003009
3010 // Publish the event.
3011 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003012 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3013 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003014 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003015 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3016 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003017
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003018 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003019 status = connection->inputPublisher
3020 .publishKeyEvent(dispatchEntry->seq,
3021 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3022 keyEntry.source, keyEntry.displayId,
3023 std::move(hmac), dispatchEntry->resolvedAction,
3024 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3025 keyEntry.scanCode, keyEntry.metaState,
3026 keyEntry.repeatCount, keyEntry.downTime,
3027 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003028 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003029 }
3030
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003031 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003032 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003033
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003034 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003035 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003036
chaviw82357092020-01-28 13:13:06 -08003037 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003038 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003039 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3040 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003041 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003042 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3043 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003044 // Don't apply window scale here since we don't want scale to affect raw
3045 // coordinates. The scale will be sent back to the client and applied
3046 // later when requesting relative coordinates.
3047 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3048 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003049 }
3050 usingCoords = scaledCoords;
3051 }
3052 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003053 // We don't want the dispatch target to know.
3054 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003055 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003056 scaledCoords[i].clear();
3057 }
3058 usingCoords = scaledCoords;
3059 }
3060 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003061
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003062 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003063
3064 // Publish the motion event.
3065 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003066 .publishMotionEvent(dispatchEntry->seq,
3067 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003068 motionEntry.deviceId, motionEntry.source,
3069 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003070 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003071 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003072 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003073 motionEntry.edgeFlags, motionEntry.metaState,
3074 motionEntry.buttonState,
3075 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003076 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003077 motionEntry.xPrecision, motionEntry.yPrecision,
3078 motionEntry.xCursorPosition,
3079 motionEntry.yCursorPosition,
3080 motionEntry.downTime, motionEntry.eventTime,
3081 motionEntry.pointerCount,
3082 motionEntry.pointerProperties, usingCoords);
3083 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003084 break;
3085 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003086
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003087 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003088 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003089 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003090 focusEntry.id,
3091 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003092 mInTouchMode);
3093 break;
3094 }
3095
Prabir Pradhan99987712020-11-10 18:43:05 -08003096 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3097 const auto& captureEntry =
3098 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3099 status = connection->inputPublisher
3100 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
3101 captureEntry.pointerCaptureEnabled);
3102 break;
3103 }
3104
arthurhungb89ccb02020-12-30 16:19:01 +08003105 case EventEntry::Type::DRAG: {
3106 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3107 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3108 dragEntry.id, dragEntry.x,
3109 dragEntry.y,
3110 dragEntry.isExiting);
3111 break;
3112 }
3113
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003114 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003115 case EventEntry::Type::DEVICE_RESET:
3116 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003117 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Chris Yef59a2f42020-10-16 12:55:26 -07003118 NamedEnum::string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003119 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003120 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003121 }
3122
3123 // Check the result.
3124 if (status) {
3125 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003126 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003127 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003128 "This is unexpected because the wait queue is empty, so the pipe "
3129 "should be empty and we shouldn't have any problems writing an "
3130 "event to it, status=%d",
3131 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003132 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3133 } else {
3134 // Pipe is full and we are waiting for the app to finish process some events
3135 // before sending more events to it.
3136#if DEBUG_DISPATCH_CYCLE
3137 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003138 "waiting for the application to catch up",
3139 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003140#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003141 }
3142 } else {
3143 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003144 "status=%d",
3145 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003146 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3147 }
3148 return;
3149 }
3150
3151 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003152 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3153 connection->outboundQueue.end(),
3154 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003155 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003156 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003157 if (connection->responsive) {
3158 mAnrTracker.insert(dispatchEntry->timeoutTime,
3159 connection->inputChannel->getConnectionToken());
3160 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003161 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003162 }
3163}
3164
chaviw09c8d2d2020-08-24 15:48:26 -07003165std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3166 size_t size;
3167 switch (event.type) {
3168 case VerifiedInputEvent::Type::KEY: {
3169 size = sizeof(VerifiedKeyEvent);
3170 break;
3171 }
3172 case VerifiedInputEvent::Type::MOTION: {
3173 size = sizeof(VerifiedMotionEvent);
3174 break;
3175 }
3176 }
3177 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3178 return mHmacKeyManager.sign(start, size);
3179}
3180
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003181const std::array<uint8_t, 32> InputDispatcher::getSignature(
3182 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3183 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3184 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3185 // Only sign events up and down events as the purely move events
3186 // are tied to their up/down counterparts so signing would be redundant.
3187 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3188 verifiedEvent.actionMasked = actionMasked;
3189 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003190 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003191 }
3192 return INVALID_HMAC;
3193}
3194
3195const std::array<uint8_t, 32> InputDispatcher::getSignature(
3196 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3197 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3198 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3199 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003200 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003201}
3202
Michael Wrightd02c5b62014-02-10 15:10:22 -08003203void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003204 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003205 bool handled, nsecs_t consumeTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003206#if DEBUG_DISPATCH_CYCLE
3207 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003208 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003209#endif
3210
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003211 if (connection->status == Connection::STATUS_BROKEN ||
3212 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003213 return;
3214 }
3215
3216 // Notify other system components and prepare to start the next dispatch cycle.
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003217 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled, consumeTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003218}
3219
3220void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003221 const sp<Connection>& connection,
3222 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003223#if DEBUG_DISPATCH_CYCLE
3224 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003225 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003226#endif
3227
3228 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003229 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003230 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003231 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003232 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003233
3234 // The connection appears to be unrecoverably broken.
3235 // Ignore already broken or zombie connections.
3236 if (connection->status == Connection::STATUS_NORMAL) {
3237 connection->status = Connection::STATUS_BROKEN;
3238
3239 if (notify) {
3240 // Notify other system components.
3241 onDispatchCycleBrokenLocked(currentTime, connection);
3242 }
3243 }
3244}
3245
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003246void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3247 while (!queue.empty()) {
3248 DispatchEntry* dispatchEntry = queue.front();
3249 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003250 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003251 }
3252}
3253
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003254void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003255 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003256 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003257 }
3258 delete dispatchEntry;
3259}
3260
3261int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
3262 InputDispatcher* d = static_cast<InputDispatcher*>(data);
3263
3264 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003265 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003266
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003267 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003268 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003269 "fd=%d, events=0x%x",
3270 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003271 return 0; // remove the callback
3272 }
3273
3274 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003275 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003276 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3277 if (!(events & ALOOPER_EVENT_INPUT)) {
3278 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003279 "events=0x%x",
3280 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003281 return 1;
3282 }
3283
3284 nsecs_t currentTime = now();
3285 bool gotOne = false;
3286 status_t status;
3287 for (;;) {
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003288 std::function<void(uint32_t seq, bool handled, nsecs_t consumeTime)> callback =
3289 std::bind(&InputDispatcher::finishDispatchCycleLocked, d, currentTime,
3290 connection, std::placeholders::_1, std::placeholders::_2,
3291 std::placeholders::_3);
3292
3293 status = connection->inputPublisher.receiveFinishedSignal(callback);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003294 if (status) {
3295 break;
3296 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003297 gotOne = true;
3298 }
3299 if (gotOne) {
3300 d->runCommandsLockedInterruptible();
3301 if (status == WOULD_BLOCK) {
3302 return 1;
3303 }
3304 }
3305
3306 notify = status != DEAD_OBJECT || !connection->monitor;
3307 if (notify) {
3308 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003309 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003310 }
3311 } else {
3312 // Monitor channels are never explicitly unregistered.
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003313 // We do it automatically when the remote endpoint is closed so don't warn about them.
arthurhungd352cb32020-04-28 17:09:28 +08003314 const bool stillHaveWindowHandle =
3315 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3316 nullptr;
3317 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318 if (notify) {
3319 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003320 "events=0x%x",
3321 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003322 }
3323 }
3324
Garfield Tan15601662020-09-22 15:32:38 -07003325 // Remove the channel.
3326 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003328 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003329}
3330
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003331void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003332 const CancelationOptions& options) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003333 for (const auto& [fd, connection] : mConnectionsByFd) {
3334 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003335 }
3336}
3337
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003338void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003339 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003340 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3341 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3342}
3343
3344void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3345 const CancelationOptions& options,
3346 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3347 for (const auto& it : monitorsByDisplay) {
3348 const std::vector<Monitor>& monitors = it.second;
3349 for (const Monitor& monitor : monitors) {
3350 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003351 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003352 }
3353}
3354
Michael Wrightd02c5b62014-02-10 15:10:22 -08003355void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003356 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003357 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003358 if (connection == nullptr) {
3359 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003360 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003361
3362 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003363}
3364
3365void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3366 const sp<Connection>& connection, const CancelationOptions& options) {
3367 if (connection->status == Connection::STATUS_BROKEN) {
3368 return;
3369 }
3370
3371 nsecs_t currentTime = now();
3372
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003373 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003374 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003375
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003376 if (cancelationEvents.empty()) {
3377 return;
3378 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003379#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003380 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3381 "with reality: %s, mode=%d.",
3382 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3383 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003384#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003385
3386 InputTarget target;
3387 sp<InputWindowHandle> windowHandle =
3388 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3389 if (windowHandle != nullptr) {
3390 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003391 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003392 target.globalScaleFactor = windowInfo->globalScaleFactor;
3393 }
3394 target.inputChannel = connection->inputChannel;
3395 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3396
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003397 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003398 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003399 switch (cancelationEventEntry->type) {
3400 case EventEntry::Type::KEY: {
3401 logOutboundKeyDetails("cancel - ",
3402 static_cast<const KeyEntry&>(*cancelationEventEntry));
3403 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003404 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003405 case EventEntry::Type::MOTION: {
3406 logOutboundMotionDetails("cancel - ",
3407 static_cast<const MotionEntry&>(*cancelationEventEntry));
3408 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003409 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003410 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08003411 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3412 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003413 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Chris Yef59a2f42020-10-16 12:55:26 -07003414 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003415 break;
3416 }
3417 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003418 case EventEntry::Type::DEVICE_RESET:
3419 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003420 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003421 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003422 break;
3423 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003424 }
3425
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003426 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3427 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003428 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003429
3430 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003431}
3432
Svet Ganov5d3bc372020-01-26 23:11:07 -08003433void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3434 const sp<Connection>& connection) {
3435 if (connection->status == Connection::STATUS_BROKEN) {
3436 return;
3437 }
3438
3439 nsecs_t currentTime = now();
3440
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003441 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003442 connection->inputState.synthesizePointerDownEvents(currentTime);
3443
3444 if (downEvents.empty()) {
3445 return;
3446 }
3447
3448#if DEBUG_OUTBOUND_EVENT_DETAILS
3449 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3450 connection->getInputChannelName().c_str(), downEvents.size());
3451#endif
3452
3453 InputTarget target;
3454 sp<InputWindowHandle> windowHandle =
3455 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3456 if (windowHandle != nullptr) {
3457 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003458 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003459 target.globalScaleFactor = windowInfo->globalScaleFactor;
3460 }
3461 target.inputChannel = connection->inputChannel;
3462 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3463
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003464 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003465 switch (downEventEntry->type) {
3466 case EventEntry::Type::MOTION: {
3467 logOutboundMotionDetails("down - ",
3468 static_cast<const MotionEntry&>(*downEventEntry));
3469 break;
3470 }
3471
3472 case EventEntry::Type::KEY:
3473 case EventEntry::Type::FOCUS:
3474 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003475 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003476 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003477 case EventEntry::Type::SENSOR:
3478 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003479 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003480 NamedEnum::string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003481 break;
3482 }
3483 }
3484
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003485 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3486 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003487 }
3488
3489 startDispatchCycleLocked(currentTime, connection);
3490}
3491
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003492std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3493 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003494 ALOG_ASSERT(pointerIds.value != 0);
3495
3496 uint32_t splitPointerIndexMap[MAX_POINTERS];
3497 PointerProperties splitPointerProperties[MAX_POINTERS];
3498 PointerCoords splitPointerCoords[MAX_POINTERS];
3499
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003500 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003501 uint32_t splitPointerCount = 0;
3502
3503 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003504 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003505 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003506 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003507 uint32_t pointerId = uint32_t(pointerProperties.id);
3508 if (pointerIds.hasBit(pointerId)) {
3509 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3510 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3511 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003512 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003513 splitPointerCount += 1;
3514 }
3515 }
3516
3517 if (splitPointerCount != pointerIds.count()) {
3518 // This is bad. We are missing some of the pointers that we expected to deliver.
3519 // Most likely this indicates that we received an ACTION_MOVE events that has
3520 // different pointer ids than we expected based on the previous ACTION_DOWN
3521 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3522 // in this way.
3523 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003524 "we expected there to be %d pointers. This probably means we received "
3525 "a broken sequence of pointer ids from the input device.",
3526 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003527 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003528 }
3529
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003530 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003531 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003532 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3533 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003534 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3535 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003536 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003537 uint32_t pointerId = uint32_t(pointerProperties.id);
3538 if (pointerIds.hasBit(pointerId)) {
3539 if (pointerIds.count() == 1) {
3540 // The first/last pointer went down/up.
3541 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003542 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003543 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3544 ? AMOTION_EVENT_ACTION_CANCEL
3545 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003546 } else {
3547 // A secondary pointer went down/up.
3548 uint32_t splitPointerIndex = 0;
3549 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3550 splitPointerIndex += 1;
3551 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003552 action = maskedAction |
3553 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003554 }
3555 } else {
3556 // An unrelated pointer changed.
3557 action = AMOTION_EVENT_ACTION_MOVE;
3558 }
3559 }
3560
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003561 int32_t newId = mIdGenerator.nextId();
3562 if (ATRACE_ENABLED()) {
3563 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3564 ") to MotionEvent(id=0x%" PRIx32 ").",
3565 originalMotionEntry.id, newId);
3566 ATRACE_NAME(message.c_str());
3567 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003568 std::unique_ptr<MotionEntry> splitMotionEntry =
3569 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3570 originalMotionEntry.deviceId, originalMotionEntry.source,
3571 originalMotionEntry.displayId,
3572 originalMotionEntry.policyFlags, action,
3573 originalMotionEntry.actionButton,
3574 originalMotionEntry.flags, originalMotionEntry.metaState,
3575 originalMotionEntry.buttonState,
3576 originalMotionEntry.classification,
3577 originalMotionEntry.edgeFlags,
3578 originalMotionEntry.xPrecision,
3579 originalMotionEntry.yPrecision,
3580 originalMotionEntry.xCursorPosition,
3581 originalMotionEntry.yCursorPosition,
3582 originalMotionEntry.downTime, splitPointerCount,
3583 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003584
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003585 if (originalMotionEntry.injectionState) {
3586 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003587 splitMotionEntry->injectionState->refCount += 1;
3588 }
3589
3590 return splitMotionEntry;
3591}
3592
3593void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3594#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003595 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003596#endif
3597
3598 bool needWake;
3599 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003600 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003601
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003602 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3603 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3604 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003605 } // release lock
3606
3607 if (needWake) {
3608 mLooper->wake();
3609 }
3610}
3611
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003612/**
3613 * If one of the meta shortcuts is detected, process them here:
3614 * Meta + Backspace -> generate BACK
3615 * Meta + Enter -> generate HOME
3616 * This will potentially overwrite keyCode and metaState.
3617 */
3618void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003619 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003620 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3621 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3622 if (keyCode == AKEYCODE_DEL) {
3623 newKeyCode = AKEYCODE_BACK;
3624 } else if (keyCode == AKEYCODE_ENTER) {
3625 newKeyCode = AKEYCODE_HOME;
3626 }
3627 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003628 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003629 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003630 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003631 keyCode = newKeyCode;
3632 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3633 }
3634 } else if (action == AKEY_EVENT_ACTION_UP) {
3635 // In order to maintain a consistent stream of up and down events, check to see if the key
3636 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3637 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003638 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003639 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003640 auto replacementIt = mReplacedKeys.find(replacement);
3641 if (replacementIt != mReplacedKeys.end()) {
3642 keyCode = replacementIt->second;
3643 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003644 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3645 }
3646 }
3647}
3648
Michael Wrightd02c5b62014-02-10 15:10:22 -08003649void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3650#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003651 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3652 "policyFlags=0x%x, action=0x%x, "
3653 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3654 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3655 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3656 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003657#endif
3658 if (!validateKeyEvent(args->action)) {
3659 return;
3660 }
3661
3662 uint32_t policyFlags = args->policyFlags;
3663 int32_t flags = args->flags;
3664 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003665 // InputDispatcher tracks and generates key repeats on behalf of
3666 // whatever notifies it, so repeatCount should always be set to 0
3667 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003668 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3669 policyFlags |= POLICY_FLAG_VIRTUAL;
3670 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3671 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003672 if (policyFlags & POLICY_FLAG_FUNCTION) {
3673 metaState |= AMETA_FUNCTION_ON;
3674 }
3675
3676 policyFlags |= POLICY_FLAG_TRUSTED;
3677
Michael Wright78f24442014-08-06 15:55:28 -07003678 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003679 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003680
Michael Wrightd02c5b62014-02-10 15:10:22 -08003681 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003682 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003683 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3684 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003685
Michael Wright2b3c3302018-03-02 17:19:13 +00003686 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003687 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003688 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3689 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003690 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003691 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003692
Michael Wrightd02c5b62014-02-10 15:10:22 -08003693 bool needWake;
3694 { // acquire lock
3695 mLock.lock();
3696
3697 if (shouldSendKeyToInputFilterLocked(args)) {
3698 mLock.unlock();
3699
3700 policyFlags |= POLICY_FLAG_FILTERED;
3701 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3702 return; // event was consumed by the filter
3703 }
3704
3705 mLock.lock();
3706 }
3707
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003708 std::unique_ptr<KeyEntry> newEntry =
3709 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3710 args->displayId, policyFlags, args->action, flags,
3711 keyCode, args->scanCode, metaState, repeatCount,
3712 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003713
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003714 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003715 mLock.unlock();
3716 } // release lock
3717
3718 if (needWake) {
3719 mLooper->wake();
3720 }
3721}
3722
3723bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3724 return mInputFilterEnabled;
3725}
3726
3727void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3728#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003729 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3730 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003731 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3732 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003733 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003734 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3735 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3736 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3737 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003738 for (uint32_t i = 0; i < args->pointerCount; i++) {
3739 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003740 "x=%f, y=%f, pressure=%f, size=%f, "
3741 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3742 "orientation=%f",
3743 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3744 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3745 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3746 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3747 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3748 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3749 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3750 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3751 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3752 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003753 }
3754#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003755 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3756 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003757 return;
3758 }
3759
3760 uint32_t policyFlags = args->policyFlags;
3761 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003762
3763 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003764 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003765 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3766 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003767 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003768 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003769
3770 bool needWake;
3771 { // acquire lock
3772 mLock.lock();
3773
3774 if (shouldSendMotionToInputFilterLocked(args)) {
3775 mLock.unlock();
3776
3777 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003778 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003779 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3780 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003781 args->metaState, args->buttonState, args->classification, transform,
3782 args->xPrecision, args->yPrecision, args->xCursorPosition,
3783 args->yCursorPosition, args->downTime, args->eventTime,
3784 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003785
3786 policyFlags |= POLICY_FLAG_FILTERED;
3787 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3788 return; // event was consumed by the filter
3789 }
3790
3791 mLock.lock();
3792 }
3793
3794 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003795 std::unique_ptr<MotionEntry> newEntry =
3796 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3797 args->source, args->displayId, policyFlags,
3798 args->action, args->actionButton, args->flags,
3799 args->metaState, args->buttonState,
3800 args->classification, args->edgeFlags,
3801 args->xPrecision, args->yPrecision,
3802 args->xCursorPosition, args->yCursorPosition,
3803 args->downTime, args->pointerCount,
3804 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003805
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003806 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003807 mLock.unlock();
3808 } // release lock
3809
3810 if (needWake) {
3811 mLooper->wake();
3812 }
3813}
3814
Chris Yef59a2f42020-10-16 12:55:26 -07003815void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
3816#if DEBUG_INBOUND_EVENT_DETAILS
3817 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3818 " sensorType=%s",
3819 args->id, args->eventTime, args->deviceId, args->source,
3820 NamedEnum::string(args->sensorType).c_str());
3821#endif
3822
3823 bool needWake;
3824 { // acquire lock
3825 mLock.lock();
3826
3827 // Just enqueue a new sensor event.
3828 std::unique_ptr<SensorEntry> newEntry =
3829 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
3830 args->source, 0 /* policyFlags*/, args->hwTimestamp,
3831 args->sensorType, args->accuracy,
3832 args->accuracyChanged, args->values);
3833
3834 needWake = enqueueInboundEventLocked(std::move(newEntry));
3835 mLock.unlock();
3836 } // release lock
3837
3838 if (needWake) {
3839 mLooper->wake();
3840 }
3841}
3842
Chris Yefb552902021-02-03 17:18:37 -08003843void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
3844#if DEBUG_INBOUND_EVENT_DETAILS
3845 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
3846 args->deviceId, args->isOn);
3847#endif
3848 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
3849}
3850
Michael Wrightd02c5b62014-02-10 15:10:22 -08003851bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003852 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003853}
3854
3855void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3856#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003857 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003858 "switchMask=0x%08x",
3859 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003860#endif
3861
3862 uint32_t policyFlags = args->policyFlags;
3863 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003864 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865}
3866
3867void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3868#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003869 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3870 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003871#endif
3872
3873 bool needWake;
3874 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003875 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003876
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003877 std::unique_ptr<DeviceResetEntry> newEntry =
3878 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3879 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003880 } // release lock
3881
3882 if (needWake) {
3883 mLooper->wake();
3884 }
3885}
3886
Prabir Pradhan7e186182020-11-10 13:56:45 -08003887void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3888#if DEBUG_INBOUND_EVENT_DETAILS
3889 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3890 args->enabled ? "true" : "false");
3891#endif
3892
Prabir Pradhan99987712020-11-10 18:43:05 -08003893 bool needWake;
3894 { // acquire lock
3895 std::scoped_lock _l(mLock);
3896 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
3897 args->enabled);
3898 needWake = enqueueInboundEventLocked(std::move(entry));
3899 } // release lock
3900
3901 if (needWake) {
3902 mLooper->wake();
3903 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003904}
3905
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003906InputEventInjectionResult InputDispatcher::injectInputEvent(
3907 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3908 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003909#if DEBUG_INBOUND_EVENT_DETAILS
3910 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003911 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3912 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003913#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003914 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003915
3916 policyFlags |= POLICY_FLAG_INJECTED;
3917 if (hasInjectionPermission(injectorPid, injectorUid)) {
3918 policyFlags |= POLICY_FLAG_TRUSTED;
3919 }
3920
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003921 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003922 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003923 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003924 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3925 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003926 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003927 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003928 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003929
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003930 int32_t flags = incomingKey.getFlags();
3931 int32_t keyCode = incomingKey.getKeyCode();
3932 int32_t metaState = incomingKey.getMetaState();
3933 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003934 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003935 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003936 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003937 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3938 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3939 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003940
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003941 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3942 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003943 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003944
3945 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3946 android::base::Timer t;
3947 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3948 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3949 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3950 std::to_string(t.duration().count()).c_str());
3951 }
3952 }
3953
3954 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003955 std::unique_ptr<KeyEntry> injectedEntry =
3956 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3957 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3958 incomingKey.getDisplayId(), policyFlags, action,
3959 flags, keyCode, incomingKey.getScanCode(), metaState,
3960 incomingKey.getRepeatCount(),
3961 incomingKey.getDownTime());
3962 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003963 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003964 }
3965
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003966 case AINPUT_EVENT_TYPE_MOTION: {
3967 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3968 int32_t action = motionEvent->getAction();
3969 size_t pointerCount = motionEvent->getPointerCount();
3970 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3971 int32_t actionButton = motionEvent->getActionButton();
3972 int32_t displayId = motionEvent->getDisplayId();
3973 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003974 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003975 }
3976
3977 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3978 nsecs_t eventTime = motionEvent->getEventTime();
3979 android::base::Timer t;
3980 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3981 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3982 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3983 std::to_string(t.duration().count()).c_str());
3984 }
3985 }
3986
3987 mLock.lock();
3988 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3989 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003990 std::unique_ptr<MotionEntry> injectedEntry =
3991 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3992 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3993 motionEvent->getDisplayId(), policyFlags, action,
3994 actionButton, motionEvent->getFlags(),
3995 motionEvent->getMetaState(),
3996 motionEvent->getButtonState(),
3997 motionEvent->getClassification(),
3998 motionEvent->getEdgeFlags(),
3999 motionEvent->getXPrecision(),
4000 motionEvent->getYPrecision(),
4001 motionEvent->getRawXCursorPosition(),
4002 motionEvent->getRawYCursorPosition(),
4003 motionEvent->getDownTime(),
4004 uint32_t(pointerCount), pointerProperties,
4005 samplePointerCoords, motionEvent->getXOffset(),
4006 motionEvent->getYOffset());
4007 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004008 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
4009 sampleEventTimes += 1;
4010 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004011 std::unique_ptr<MotionEntry> nextInjectedEntry =
4012 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
4013 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
4014 motionEvent->getDisplayId(), policyFlags,
4015 action, actionButton, motionEvent->getFlags(),
4016 motionEvent->getMetaState(),
4017 motionEvent->getButtonState(),
4018 motionEvent->getClassification(),
4019 motionEvent->getEdgeFlags(),
4020 motionEvent->getXPrecision(),
4021 motionEvent->getYPrecision(),
4022 motionEvent->getRawXCursorPosition(),
4023 motionEvent->getRawYCursorPosition(),
4024 motionEvent->getDownTime(),
4025 uint32_t(pointerCount), pointerProperties,
4026 samplePointerCoords,
4027 motionEvent->getXOffset(),
4028 motionEvent->getYOffset());
4029 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004030 }
4031 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004032 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004033
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004034 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004035 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004036 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004037 }
4038
4039 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004040 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004041 injectionState->injectionIsAsync = true;
4042 }
4043
4044 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004045 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004046
4047 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004048 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004049 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004050 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004051 }
4052
4053 mLock.unlock();
4054
4055 if (needWake) {
4056 mLooper->wake();
4057 }
4058
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004059 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004060 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004061 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004062
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004063 if (syncMode == InputEventInjectionSync::NONE) {
4064 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004065 } else {
4066 for (;;) {
4067 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004068 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004069 break;
4070 }
4071
4072 nsecs_t remainingTimeout = endTime - now();
4073 if (remainingTimeout <= 0) {
4074#if DEBUG_INJECTION
4075 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004076 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004077#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004078 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004079 break;
4080 }
4081
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004082 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004083 }
4084
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004085 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4086 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004087 while (injectionState->pendingForegroundDispatches != 0) {
4088#if DEBUG_INJECTION
4089 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004090 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004091#endif
4092 nsecs_t remainingTimeout = endTime - now();
4093 if (remainingTimeout <= 0) {
4094#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004095 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4096 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004097#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004098 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004099 break;
4100 }
4101
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004102 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004103 }
4104 }
4105 }
4106
4107 injectionState->release();
4108 } // release lock
4109
4110#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004111 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004112 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004113#endif
4114
4115 return injectionResult;
4116}
4117
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004118std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004119 std::array<uint8_t, 32> calculatedHmac;
4120 std::unique_ptr<VerifiedInputEvent> result;
4121 switch (event.getType()) {
4122 case AINPUT_EVENT_TYPE_KEY: {
4123 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4124 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4125 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004126 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004127 break;
4128 }
4129 case AINPUT_EVENT_TYPE_MOTION: {
4130 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4131 VerifiedMotionEvent verifiedMotionEvent =
4132 verifiedMotionEventFromMotionEvent(motionEvent);
4133 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004134 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004135 break;
4136 }
4137 default: {
4138 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4139 return nullptr;
4140 }
4141 }
4142 if (calculatedHmac == INVALID_HMAC) {
4143 return nullptr;
4144 }
4145 if (calculatedHmac != event.getHmac()) {
4146 return nullptr;
4147 }
4148 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004149}
4150
Michael Wrightd02c5b62014-02-10 15:10:22 -08004151bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004152 return injectorUid == 0 ||
4153 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004154}
4155
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004156void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004157 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004158 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004159 if (injectionState) {
4160#if DEBUG_INJECTION
4161 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004162 "injectorPid=%d, injectorUid=%d",
4163 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004164#endif
4165
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004166 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004167 // Log the outcome since the injector did not wait for the injection result.
4168 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004169 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004170 ALOGV("Asynchronous input event injection succeeded.");
4171 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004172 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004173 ALOGW("Asynchronous input event injection failed.");
4174 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004175 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004176 ALOGW("Asynchronous input event injection permission denied.");
4177 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004178 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004179 ALOGW("Asynchronous input event injection timed out.");
4180 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004181 case InputEventInjectionResult::PENDING:
4182 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4183 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004184 }
4185 }
4186
4187 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004188 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004189 }
4190}
4191
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004192void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4193 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004194 if (injectionState) {
4195 injectionState->pendingForegroundDispatches += 1;
4196 }
4197}
4198
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004199void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4200 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004201 if (injectionState) {
4202 injectionState->pendingForegroundDispatches -= 1;
4203
4204 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004205 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004206 }
4207 }
4208}
4209
Vishnu Nairad321cd2020-08-20 16:40:21 -07004210const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004211 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004212 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
4213 auto it = mWindowHandlesByDisplay.find(displayId);
4214 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004215}
4216
Michael Wrightd02c5b62014-02-10 15:10:22 -08004217sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004218 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004219 if (windowHandleToken == nullptr) {
4220 return nullptr;
4221 }
4222
Arthur Hungb92218b2018-08-14 12:00:21 +08004223 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004224 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004225 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004226 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004227 return windowHandle;
4228 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004229 }
4230 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004231 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004232}
4233
Vishnu Nairad321cd2020-08-20 16:40:21 -07004234sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4235 int displayId) const {
4236 if (windowHandleToken == nullptr) {
4237 return nullptr;
4238 }
4239
4240 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
4241 if (windowHandle->getToken() == windowHandleToken) {
4242 return windowHandle;
4243 }
4244 }
4245 return nullptr;
4246}
4247
4248sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Vishnu Nairc519ff72021-01-21 08:23:08 -08004249 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004250 return getWindowHandleLocked(focusedToken, displayId);
4251}
4252
Mady Mellor017bcd12020-06-23 19:12:00 +00004253bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
4254 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004255 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00004256 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004257 if (handle->getId() == windowHandle->getId() &&
4258 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004259 if (windowHandle->getInfo()->displayId != it.first) {
4260 ALOGE("Found window %s in display %" PRId32
4261 ", but it should belong to display %" PRId32,
4262 windowHandle->getName().c_str(), it.first,
4263 windowHandle->getInfo()->displayId);
4264 }
4265 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08004266 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004267 }
4268 }
4269 return false;
4270}
4271
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004272bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
4273 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4274 const bool noInputChannel =
4275 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4276 if (connection != nullptr && noInputChannel) {
4277 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4278 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4279 return false;
4280 }
4281
4282 if (connection == nullptr) {
4283 if (!noInputChannel) {
4284 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4285 }
4286 return false;
4287 }
4288 if (!connection->responsive) {
4289 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4290 return false;
4291 }
4292 return true;
4293}
4294
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004295std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4296 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07004297 size_t count = mInputChannelsByToken.count(token);
4298 if (count == 0) {
4299 return nullptr;
4300 }
4301 return mInputChannelsByToken.at(token);
4302}
4303
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004304void InputDispatcher::updateWindowHandlesForDisplayLocked(
4305 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
4306 if (inputWindowHandles.empty()) {
4307 // Remove all handles on a display if there are no windows left.
4308 mWindowHandlesByDisplay.erase(displayId);
4309 return;
4310 }
4311
4312 // Since we compare the pointer of input window handles across window updates, we need
4313 // to make sure the handle object for the same window stays unchanged across updates.
4314 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07004315 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004316 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004317 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004318 }
4319
4320 std::vector<sp<InputWindowHandle>> newHandles;
4321 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
4322 if (!handle->updateInfo()) {
4323 // handle no longer valid
4324 continue;
4325 }
4326
4327 const InputWindowInfo* info = handle->getInfo();
4328 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4329 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4330 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01004331 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4332 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
4333 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004334 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004335 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004336 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004337 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004338 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004339 }
4340
4341 if (info->displayId != displayId) {
4342 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4343 handle->getName().c_str(), displayId, info->displayId);
4344 continue;
4345 }
4346
Robert Carredd13602020-04-13 17:24:34 -07004347 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4348 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004349 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004350 oldHandle->updateFrom(handle);
4351 newHandles.push_back(oldHandle);
4352 } else {
4353 newHandles.push_back(handle);
4354 }
4355 }
4356
4357 // Insert or replace
4358 mWindowHandlesByDisplay[displayId] = newHandles;
4359}
4360
Arthur Hung72d8dc32020-03-28 00:48:39 +00004361void InputDispatcher::setInputWindows(
4362 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4363 { // acquire lock
4364 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004365 for (const auto& [displayId, handles] : handlesPerDisplay) {
4366 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004367 }
4368 }
4369 // Wake up poll loop since it may need to make new input dispatching choices.
4370 mLooper->wake();
4371}
4372
Arthur Hungb92218b2018-08-14 12:00:21 +08004373/**
4374 * Called from InputManagerService, update window handle list by displayId that can receive input.
4375 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4376 * If set an empty list, remove all handles from the specific display.
4377 * For focused handle, check if need to change and send a cancel event to previous one.
4378 * For removed handle, check if need to send a cancel event if already in touch.
4379 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004380void InputDispatcher::setInputWindowsLocked(
4381 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004382 if (DEBUG_FOCUS) {
4383 std::string windowList;
4384 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4385 windowList += iwh->getName() + " ";
4386 }
4387 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4388 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004389
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004390 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4391 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4392 const bool noInputWindow =
4393 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4394 if (noInputWindow && window->getToken() != nullptr) {
4395 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4396 window->getName().c_str());
4397 window->releaseChannel();
4398 }
4399 }
4400
Arthur Hung72d8dc32020-03-28 00:48:39 +00004401 // Copy old handles for release if they are no longer present.
4402 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004403
Arthur Hung72d8dc32020-03-28 00:48:39 +00004404 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004405
Vishnu Nair958da932020-08-21 17:12:37 -07004406 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4407 if (mLastHoverWindowHandle &&
4408 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4409 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004410 mLastHoverWindowHandle = nullptr;
4411 }
4412
Vishnu Nairc519ff72021-01-21 08:23:08 -08004413 std::optional<FocusResolver::FocusChanges> changes =
4414 mFocusResolver.setInputWindows(displayId, windowHandles);
4415 if (changes) {
4416 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004417 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004418
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004419 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4420 mTouchStatesByDisplay.find(displayId);
4421 if (stateIt != mTouchStatesByDisplay.end()) {
4422 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004423 for (size_t i = 0; i < state.windows.size();) {
4424 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004425 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004426 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004427 ALOGD("Touched window was removed: %s in display %" PRId32,
4428 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004429 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004430 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004431 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4432 if (touchedInputChannel != nullptr) {
4433 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4434 "touched window was removed");
4435 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004436 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004437 state.windows.erase(state.windows.begin() + i);
4438 } else {
4439 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004440 }
4441 }
arthurhungb89ccb02020-12-30 16:19:01 +08004442
4443 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. we
4444 // could just clear the state here.
4445 if (state.dragWindow &&
4446 std::find(windowHandles.begin(), windowHandles.end(), state.dragWindow) ==
4447 windowHandles.end()) {
4448 state.dragWindow = nullptr;
4449 state.dragHoverWindowHandle = nullptr;
4450 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004451 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004452
Arthur Hung72d8dc32020-03-28 00:48:39 +00004453 // Release information for windows that are no longer present.
4454 // This ensures that unused input channels are released promptly.
4455 // Otherwise, they might stick around until the window handle is destroyed
4456 // which might not happen until the next GC.
4457 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004458 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004459 if (DEBUG_FOCUS) {
4460 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004461 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004462 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004463 // To avoid making too many calls into the compat framework, only
4464 // check for window flags when windows are going away.
4465 // TODO(b/157929241) : delete this. This is only needed temporarily
4466 // in order to gather some data about the flag usage
4467 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4468 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4469 oldWindowHandle->getName().c_str());
4470 if (mCompatService != nullptr) {
4471 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4472 oldWindowHandle->getInfo()->ownerUid);
4473 }
4474 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004475 }
chaviw291d88a2019-02-14 10:33:58 -08004476 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004477}
4478
4479void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004480 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004481 if (DEBUG_FOCUS) {
4482 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4483 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4484 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004485 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004486 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004487
Chris Yea209fde2020-07-22 13:54:51 -07004488 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004489 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004490
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004491 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4492 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004493 }
4494
Chris Yea209fde2020-07-22 13:54:51 -07004495 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004496 if (inputApplicationHandle != nullptr) {
4497 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4498 } else {
4499 mFocusedApplicationHandlesByDisplay.erase(displayId);
4500 }
4501
4502 // No matter what the old focused application was, stop waiting on it because it is
4503 // no longer focused.
4504 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004505 } // release lock
4506
4507 // Wake up poll loop since it may need to make new input dispatching choices.
4508 mLooper->wake();
4509}
4510
Tiger Huang721e26f2018-07-24 22:26:19 +08004511/**
4512 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4513 * the display not specified.
4514 *
4515 * We track any unreleased events for each window. If a window loses the ability to receive the
4516 * released event, we will send a cancel event to it. So when the focused display is changed, we
4517 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4518 * display. The display-specified events won't be affected.
4519 */
4520void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004521 if (DEBUG_FOCUS) {
4522 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4523 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004524 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004525 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004526
4527 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004528 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004529 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004530 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004531 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004532 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004533 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004534 CancelationOptions
4535 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4536 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004537 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004538 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4539 }
4540 }
4541 mFocusedDisplayId = displayId;
4542
Chris Ye3c2d6f52020-08-09 10:39:48 -07004543 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004544 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004545 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004546
Vishnu Nairad321cd2020-08-20 16:40:21 -07004547 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004548 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004549 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004550 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004551 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004552 }
4553 }
4554 }
4555
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004556 if (DEBUG_FOCUS) {
4557 logDispatchStateLocked();
4558 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004559 } // release lock
4560
4561 // Wake up poll loop since it may need to make new input dispatching choices.
4562 mLooper->wake();
4563}
4564
Michael Wrightd02c5b62014-02-10 15:10:22 -08004565void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004566 if (DEBUG_FOCUS) {
4567 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4568 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004569
4570 bool changed;
4571 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004572 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004573
4574 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4575 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004576 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004577 }
4578
4579 if (mDispatchEnabled && !enabled) {
4580 resetAndDropEverythingLocked("dispatcher is being disabled");
4581 }
4582
4583 mDispatchEnabled = enabled;
4584 mDispatchFrozen = frozen;
4585 changed = true;
4586 } else {
4587 changed = false;
4588 }
4589
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004590 if (DEBUG_FOCUS) {
4591 logDispatchStateLocked();
4592 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004593 } // release lock
4594
4595 if (changed) {
4596 // Wake up poll loop since it may need to make new input dispatching choices.
4597 mLooper->wake();
4598 }
4599}
4600
4601void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004602 if (DEBUG_FOCUS) {
4603 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4604 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004605
4606 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004607 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004608
4609 if (mInputFilterEnabled == enabled) {
4610 return;
4611 }
4612
4613 mInputFilterEnabled = enabled;
4614 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4615 } // release lock
4616
4617 // Wake up poll loop since there might be work to do to drop everything.
4618 mLooper->wake();
4619}
4620
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004621void InputDispatcher::setInTouchMode(bool inTouchMode) {
4622 std::scoped_lock lock(mLock);
4623 mInTouchMode = inTouchMode;
4624}
4625
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004626void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4627 if (opacity < 0 || opacity > 1) {
4628 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4629 return;
4630 }
4631
4632 std::scoped_lock lock(mLock);
4633 mMaximumObscuringOpacityForTouch = opacity;
4634}
4635
4636void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4637 std::scoped_lock lock(mLock);
4638 mBlockUntrustedTouchesMode = mode;
4639}
4640
arthurhungb89ccb02020-12-30 16:19:01 +08004641bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4642 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004643 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004644 if (DEBUG_FOCUS) {
4645 ALOGD("Trivial transfer to same window.");
4646 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004647 return true;
4648 }
4649
Michael Wrightd02c5b62014-02-10 15:10:22 -08004650 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004651 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004652
chaviwfbe5d9c2018-12-26 12:23:37 -08004653 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4654 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004655 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004656 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004657 return false;
4658 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004659 if (DEBUG_FOCUS) {
4660 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4661 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4662 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004663 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004664 if (DEBUG_FOCUS) {
4665 ALOGD("Cannot transfer focus because windows are on different displays.");
4666 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004667 return false;
4668 }
4669
4670 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004671 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4672 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004673 for (size_t i = 0; i < state.windows.size(); i++) {
4674 const TouchedWindow& touchedWindow = state.windows[i];
4675 if (touchedWindow.windowHandle == fromWindowHandle) {
4676 int32_t oldTargetFlags = touchedWindow.targetFlags;
4677 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004678
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004679 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004680
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004681 int32_t newTargetFlags = oldTargetFlags &
4682 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4683 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004684 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004685
arthurhungb89ccb02020-12-30 16:19:01 +08004686 // Store the dragging window.
4687 if (isDragDrop) {
4688 state.dragWindow = toWindowHandle;
4689 }
4690
Jeff Brownf086ddb2014-02-11 14:28:48 -08004691 found = true;
4692 goto Found;
4693 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004694 }
4695 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004696 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004697
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004698 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004699 if (DEBUG_FOCUS) {
4700 ALOGD("Focus transfer failed because from window did not have focus.");
4701 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004702 return false;
4703 }
4704
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004705 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4706 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004707 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004708 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004709 CancelationOptions
4710 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4711 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004712 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004713 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004714 }
4715
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004716 if (DEBUG_FOCUS) {
4717 logDispatchStateLocked();
4718 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004719 } // release lock
4720
4721 // Wake up poll loop since it may need to make new input dispatching choices.
4722 mLooper->wake();
4723 return true;
4724}
4725
4726void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004727 if (DEBUG_FOCUS) {
4728 ALOGD("Resetting and dropping all events (%s).", reason);
4729 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004730
4731 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4732 synthesizeCancelationEventsForAllConnectionsLocked(options);
4733
4734 resetKeyRepeatLocked();
4735 releasePendingEventLocked();
4736 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004737 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004738
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004739 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004740 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004741 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004742 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004743}
4744
4745void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004746 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004747 dumpDispatchStateLocked(dump);
4748
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004749 std::istringstream stream(dump);
4750 std::string line;
4751
4752 while (std::getline(stream, line, '\n')) {
4753 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004754 }
4755}
4756
Prabir Pradhan99987712020-11-10 18:43:05 -08004757std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4758 std::string dump;
4759
4760 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4761 toString(mFocusedWindowRequestedPointerCapture));
4762
4763 std::string windowName = "None";
4764 if (mWindowTokenWithPointerCapture) {
4765 const sp<InputWindowHandle> captureWindowHandle =
4766 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4767 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4768 : "token has capture without window";
4769 }
4770 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4771
4772 return dump;
4773}
4774
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004775void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004776 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4777 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4778 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004779 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004780
Tiger Huang721e26f2018-07-24 22:26:19 +08004781 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4782 dump += StringPrintf(INDENT "FocusedApplications:\n");
4783 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4784 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004785 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004786 const std::chrono::duration timeout =
4787 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004788 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004789 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004790 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004791 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004792 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004793 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004794 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004795
Vishnu Nairc519ff72021-01-21 08:23:08 -08004796 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08004797 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004798
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004799 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004800 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004801 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4802 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004803 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004804 state.displayId, toString(state.down), toString(state.split),
4805 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004806 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004807 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004808 for (size_t i = 0; i < state.windows.size(); i++) {
4809 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004810 dump += StringPrintf(INDENT4
4811 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4812 i, touchedWindow.windowHandle->getName().c_str(),
4813 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004814 }
4815 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004816 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004817 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004818 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004819 dump += INDENT3 "Portal windows:\n";
4820 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004821 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004822 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4823 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004824 }
4825 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004826 }
4827 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004828 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004829 }
4830
Arthur Hungb92218b2018-08-14 12:00:21 +08004831 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004832 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004833 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004834 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004835 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004836 dump += INDENT2 "Windows:\n";
4837 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004838 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004839 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004840
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004841 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004842 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004843 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004844 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004845 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00004846 "applicationInfo.name=%s, "
4847 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004848 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004849 i, windowInfo->name.c_str(), windowInfo->id,
4850 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004851 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004852 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004853 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004854 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004855 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004856 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004857 windowInfo->frameLeft, windowInfo->frameTop,
4858 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004859 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00004860 windowInfo->applicationInfo.name.c_str(),
4861 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004862 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004863 dump += StringPrintf(", inputFeatures=%s",
4864 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004865 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004866 "ms, trustedOverlay=%s, hasToken=%s, "
4867 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004868 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004869 millis(windowInfo->dispatchingTimeout),
4870 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004871 toString(windowInfo->token != nullptr),
4872 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004873 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004874 }
4875 } else {
4876 dump += INDENT2 "Windows: <none>\n";
4877 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004878 }
4879 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004880 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004881 }
4882
Michael Wright3dd60e22019-03-27 22:06:44 +00004883 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004884 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004885 const std::vector<Monitor>& monitors = it.second;
4886 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4887 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004888 }
4889 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004890 const std::vector<Monitor>& monitors = it.second;
4891 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4892 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004893 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004894 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004895 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004896 }
4897
4898 nsecs_t currentTime = now();
4899
4900 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004901 if (!mRecentQueue.empty()) {
4902 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004903 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004904 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004905 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004906 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004907 }
4908 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004909 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004910 }
4911
4912 // Dump event currently being dispatched.
4913 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004914 dump += INDENT "PendingEvent:\n";
4915 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004916 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004917 dump += StringPrintf(", age=%" PRId64 "ms\n",
4918 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004919 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004920 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004921 }
4922
4923 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004924 if (!mInboundQueue.empty()) {
4925 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004926 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004927 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004928 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004929 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004930 }
4931 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004932 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004933 }
4934
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004935 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004936 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004937 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4938 const KeyReplacement& replacement = pair.first;
4939 int32_t newKeyCode = pair.second;
4940 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004941 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004942 }
4943 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004944 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004945 }
4946
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004947 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004948 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004949 for (const auto& pair : mConnectionsByFd) {
4950 const sp<Connection>& connection = pair.second;
4951 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004952 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004953 pair.first, connection->getInputChannelName().c_str(),
4954 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004955 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004956
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004957 if (!connection->outboundQueue.empty()) {
4958 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4959 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004960 dump += dumpQueue(connection->outboundQueue, currentTime);
4961
Michael Wrightd02c5b62014-02-10 15:10:22 -08004962 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004963 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004964 }
4965
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004966 if (!connection->waitQueue.empty()) {
4967 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4968 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004969 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004970 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004971 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004972 }
4973 }
4974 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004975 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004976 }
4977
4978 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004979 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4980 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004981 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004982 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004983 }
4984
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004985 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004986 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4987 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4988 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004989}
4990
Michael Wright3dd60e22019-03-27 22:06:44 +00004991void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4992 const size_t numMonitors = monitors.size();
4993 for (size_t i = 0; i < numMonitors; i++) {
4994 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004995 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004996 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4997 dump += "\n";
4998 }
4999}
5000
Garfield Tan15601662020-09-22 15:32:38 -07005001base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
5002 const std::string& name) {
5003#if DEBUG_CHANNEL_CREATION
5004 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005005#endif
5006
Garfield Tan15601662020-09-22 15:32:38 -07005007 std::shared_ptr<InputChannel> serverChannel;
5008 std::unique_ptr<InputChannel> clientChannel;
5009 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5010
5011 if (result) {
5012 return base::Error(result) << "Failed to open input channel pair with name " << name;
5013 }
5014
Michael Wrightd02c5b62014-02-10 15:10:22 -08005015 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005016 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07005017 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005018
Garfield Tan15601662020-09-22 15:32:38 -07005019 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005020 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07005021 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005022
Michael Wrightd02c5b62014-02-10 15:10:22 -08005023 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
5024 } // release lock
5025
5026 // Wake the looper because some connections have changed.
5027 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005028 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005029}
5030
Garfield Tan15601662020-09-22 15:32:38 -07005031base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005032 int32_t displayId, bool isGestureMonitor, const std::string& name, int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005033 std::shared_ptr<InputChannel> serverChannel;
5034 std::unique_ptr<InputChannel> clientChannel;
5035 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5036 if (result) {
5037 return base::Error(result) << "Failed to open input channel pair with name " << name;
5038 }
5039
Michael Wright3dd60e22019-03-27 22:06:44 +00005040 { // acquire lock
5041 std::scoped_lock _l(mLock);
5042
5043 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005044 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5045 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005046 }
5047
Garfield Tan15601662020-09-22 15:32:38 -07005048 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00005049
Garfield Tan15601662020-09-22 15:32:38 -07005050 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005051 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07005052 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005053
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005054 auto& monitorsByDisplay =
5055 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005056 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005057
5058 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00005059 }
Garfield Tan15601662020-09-22 15:32:38 -07005060
Michael Wright3dd60e22019-03-27 22:06:44 +00005061 // Wake the looper because some connections have changed.
5062 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005063 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005064}
5065
Garfield Tan15601662020-09-22 15:32:38 -07005066status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005067 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005068 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005069
Garfield Tan15601662020-09-22 15:32:38 -07005070 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005071 if (status) {
5072 return status;
5073 }
5074 } // release lock
5075
5076 // Wake the poll loop because removing the connection may have changed the current
5077 // synchronization state.
5078 mLooper->wake();
5079 return OK;
5080}
5081
Garfield Tan15601662020-09-22 15:32:38 -07005082status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5083 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005084 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005085 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005086 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005087 return BAD_VALUE;
5088 }
5089
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005090 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005091 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07005092
Michael Wrightd02c5b62014-02-10 15:10:22 -08005093 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005094 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005095 }
5096
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005097 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005098
5099 nsecs_t currentTime = now();
5100 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5101
5102 connection->status = Connection::STATUS_ZOMBIE;
5103 return OK;
5104}
5105
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005106void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5107 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5108 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005109}
5110
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005111void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005112 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005113 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005114 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005115 std::vector<Monitor>& monitors = it->second;
5116 const size_t numMonitors = monitors.size();
5117 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005118 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005119 monitors.erase(monitors.begin() + i);
5120 break;
5121 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005122 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005123 if (monitors.empty()) {
5124 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005125 } else {
5126 ++it;
5127 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005128 }
5129}
5130
Michael Wright3dd60e22019-03-27 22:06:44 +00005131status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5132 { // acquire lock
5133 std::scoped_lock _l(mLock);
5134 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5135
5136 if (!foundDisplayId) {
5137 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5138 return BAD_VALUE;
5139 }
5140 int32_t displayId = foundDisplayId.value();
5141
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005142 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5143 mTouchStatesByDisplay.find(displayId);
5144 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005145 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5146 return BAD_VALUE;
5147 }
5148
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005149 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005150 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005151 std::optional<int32_t> foundDeviceId;
5152 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005153 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005154 requestingChannel = touchedMonitor.monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005155 foundDeviceId = state.deviceId;
5156 }
5157 }
5158 if (!foundDeviceId || !state.down) {
5159 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005160 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005161 return BAD_VALUE;
5162 }
5163 int32_t deviceId = foundDeviceId.value();
5164
5165 // Send cancel events to all the input channels we're stealing from.
5166 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005167 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005168 options.deviceId = deviceId;
5169 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005170 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005171 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005172 std::shared_ptr<InputChannel> channel =
5173 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005174 if (channel != nullptr) {
5175 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005176 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005177 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005178 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005179 canceledWindows += "]";
5180 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5181 canceledWindows.c_str());
5182
Michael Wright3dd60e22019-03-27 22:06:44 +00005183 // Then clear the current touch state so we stop dispatching to them as well.
5184 state.filterNonMonitors();
5185 }
5186 return OK;
5187}
5188
Prabir Pradhan99987712020-11-10 18:43:05 -08005189void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5190 { // acquire lock
5191 std::scoped_lock _l(mLock);
5192 if (DEBUG_FOCUS) {
5193 const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
5194 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5195 windowHandle != nullptr ? windowHandle->getName().c_str()
5196 : "token without window");
5197 }
5198
Vishnu Nairc519ff72021-01-21 08:23:08 -08005199 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005200 if (focusedToken != windowToken) {
5201 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5202 enabled ? "enable" : "disable");
5203 return;
5204 }
5205
5206 if (enabled == mFocusedWindowRequestedPointerCapture) {
5207 ALOGW("Ignoring request to %s Pointer Capture: "
5208 "window has %s requested pointer capture.",
5209 enabled ? "enable" : "disable", enabled ? "already" : "not");
5210 return;
5211 }
5212
5213 mFocusedWindowRequestedPointerCapture = enabled;
5214 setPointerCaptureLocked(enabled);
5215 } // release lock
5216
5217 // Wake the thread to process command entries.
5218 mLooper->wake();
5219}
5220
Michael Wright3dd60e22019-03-27 22:06:44 +00005221std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5222 const sp<IBinder>& token) {
5223 for (const auto& it : mGestureMonitorsByDisplay) {
5224 const std::vector<Monitor>& monitors = it.second;
5225 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005226 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005227 return it.first;
5228 }
5229 }
5230 }
5231 return std::nullopt;
5232}
5233
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005234std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5235 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5236 if (gesturePid.has_value()) {
5237 return gesturePid;
5238 }
5239 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5240}
5241
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005242sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005243 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005244 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005245 }
5246
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005247 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005248 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005249 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005250 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005251 }
5252 }
Robert Carr4e670e52018-08-15 13:26:12 -07005253
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005254 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005255}
5256
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005257std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5258 sp<Connection> connection = getConnectionLocked(connectionToken);
5259 if (connection == nullptr) {
5260 return "<nullptr>";
5261 }
5262 return connection->getInputChannelName();
5263}
5264
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005265void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005266 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005267 removeByValue(mConnectionsByFd, connection);
5268}
5269
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005270void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5271 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10005272 bool handled, nsecs_t consumeTime) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005273 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5274 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005275 commandEntry->connection = connection;
5276 commandEntry->eventTime = currentTime;
5277 commandEntry->seq = seq;
5278 commandEntry->handled = handled;
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10005279 commandEntry->consumeTime = consumeTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005280 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005281}
5282
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005283void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5284 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005285 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005286 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005287
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005288 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5289 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005290 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005291 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005292}
5293
Vishnu Nairad321cd2020-08-20 16:40:21 -07005294void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5295 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005296 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5297 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005298 commandEntry->oldToken = oldToken;
5299 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005300 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005301}
5302
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005303void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5304 if (connection == nullptr) {
5305 LOG_ALWAYS_FATAL("Caller must check for nullness");
5306 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005307 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5308 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005309 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005310 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005311 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005312 return;
5313 }
5314 /**
5315 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5316 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5317 * has changed. This could cause newer entries to time out before the already dispatched
5318 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5319 * processes the events linearly. So providing information about the oldest entry seems to be
5320 * most useful.
5321 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005322 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005323 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5324 std::string reason =
5325 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005326 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005327 ns2ms(currentWait),
5328 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005329 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005330 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005331
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005332 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5333
5334 // Stop waking up for events on this connection, it is already unresponsive
5335 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005336}
5337
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005338void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5339 std::string reason =
5340 StringPrintf("%s does not have a focused window", application->getName().c_str());
5341 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005342
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005343 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5344 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5345 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005346 postCommandLocked(std::move(commandEntry));
5347}
5348
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005349void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5350 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5351 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5352 commandEntry->obscuringPackage = obscuringPackage;
5353 postCommandLocked(std::move(commandEntry));
5354}
5355
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005356void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
5357 const std::string& reason) {
5358 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5359 updateLastAnrStateLocked(windowLabel, reason);
5360}
5361
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005362void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5363 const std::string& reason) {
5364 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005365 updateLastAnrStateLocked(windowLabel, reason);
5366}
5367
5368void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5369 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005370 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005371 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005372 struct tm tm;
5373 localtime_r(&t, &tm);
5374 char timestr[64];
5375 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005376 mLastAnrState.clear();
5377 mLastAnrState += INDENT "ANR:\n";
5378 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005379 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5380 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005381 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005382}
5383
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005384void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005385 mLock.unlock();
5386
5387 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5388
5389 mLock.lock();
5390}
5391
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005392void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005393 sp<Connection> connection = commandEntry->connection;
5394
5395 if (connection->status != Connection::STATUS_ZOMBIE) {
5396 mLock.unlock();
5397
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005398 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005399
5400 mLock.lock();
5401 }
5402}
5403
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005404void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005405 sp<IBinder> oldToken = commandEntry->oldToken;
5406 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005407 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005408 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005409 mLock.lock();
5410}
5411
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005412void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005413 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005414
5415 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5416
5417 mLock.lock();
5418}
5419
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005420void InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005421 mLock.unlock();
5422
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005423 mPolicy->notifyWindowUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005424
5425 mLock.lock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005426}
5427
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005428void InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005429 mLock.unlock();
5430
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005431 mPolicy->notifyMonitorUnresponsive(commandEntry->pid, commandEntry->reason);
5432
5433 mLock.lock();
5434}
5435
5436void InputDispatcher::doNotifyWindowResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5437 mLock.unlock();
5438
5439 mPolicy->notifyWindowResponsive(commandEntry->connectionToken);
5440
5441 mLock.lock();
5442}
5443
5444void InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5445 mLock.unlock();
5446
5447 mPolicy->notifyMonitorResponsive(commandEntry->pid);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005448
5449 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005450}
5451
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005452void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5453 mLock.unlock();
5454
5455 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5456
5457 mLock.lock();
5458}
5459
Michael Wrightd02c5b62014-02-10 15:10:22 -08005460void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5461 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005462 KeyEntry& entry = *(commandEntry->keyEntry);
5463 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005464
5465 mLock.unlock();
5466
Michael Wright2b3c3302018-03-02 17:19:13 +00005467 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005468 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005469 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005470 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5471 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005472 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005473 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005474
5475 mLock.lock();
5476
5477 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005478 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005479 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005480 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005481 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005482 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5483 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005484 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005485}
5486
chaviwfd6d3512019-03-25 13:23:49 -07005487void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5488 mLock.unlock();
5489 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5490 mLock.lock();
5491}
5492
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005493/**
5494 * Connection is responsive if it has no events in the waitQueue that are older than the
5495 * current time.
5496 */
5497static bool isConnectionResponsive(const Connection& connection) {
5498 const nsecs_t currentTime = now();
5499 for (const DispatchEntry* entry : connection.waitQueue) {
5500 if (entry->timeoutTime < currentTime) {
5501 return false;
5502 }
5503 }
5504 return true;
5505}
5506
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005507void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005508 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005509 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005510 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005511 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005512
5513 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005514 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005515 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005516 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005517 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005518 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005519 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005520 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005521 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5522 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005523 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005524 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005525
5526 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005527 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005528 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005529 restartEvent =
5530 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005531 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005532 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005533 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5534 handled);
5535 } else {
5536 restartEvent = false;
5537 }
5538
5539 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005540 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005541 // contents of the wait queue to have been drained, so we need to double-check
5542 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005543 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5544 if (dispatchEntryIt != connection->waitQueue.end()) {
5545 dispatchEntry = *dispatchEntryIt;
5546 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005547 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5548 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005549 if (!connection->responsive) {
5550 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005551 if (connection->responsive) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005552 // The connection was unresponsive, and now it's responsive.
5553 processConnectionResponsiveLocked(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005554 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005555 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005556 traceWaitQueueLength(connection);
5557 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005558 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005559 traceOutboundQueueLength(connection);
5560 } else {
5561 releaseDispatchEntry(dispatchEntry);
5562 }
5563 }
5564
5565 // Start the next dispatch cycle for this connection.
5566 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005567}
5568
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005569void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
5570 std::unique_ptr<CommandEntry> monitorUnresponsiveCommand = std::make_unique<CommandEntry>(
5571 &InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible);
5572 monitorUnresponsiveCommand->pid = pid;
5573 monitorUnresponsiveCommand->reason = std::move(reason);
5574 postCommandLocked(std::move(monitorUnresponsiveCommand));
5575}
5576
5577void InputDispatcher::sendWindowUnresponsiveCommandLocked(sp<IBinder> connectionToken,
5578 std::string reason) {
5579 std::unique_ptr<CommandEntry> windowUnresponsiveCommand = std::make_unique<CommandEntry>(
5580 &InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible);
5581 windowUnresponsiveCommand->connectionToken = std::move(connectionToken);
5582 windowUnresponsiveCommand->reason = std::move(reason);
5583 postCommandLocked(std::move(windowUnresponsiveCommand));
5584}
5585
5586void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
5587 std::unique_ptr<CommandEntry> monitorResponsiveCommand = std::make_unique<CommandEntry>(
5588 &InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible);
5589 monitorResponsiveCommand->pid = pid;
5590 postCommandLocked(std::move(monitorResponsiveCommand));
5591}
5592
5593void InputDispatcher::sendWindowResponsiveCommandLocked(sp<IBinder> connectionToken) {
5594 std::unique_ptr<CommandEntry> windowResponsiveCommand = std::make_unique<CommandEntry>(
5595 &InputDispatcher::doNotifyWindowResponsiveLockedInterruptible);
5596 windowResponsiveCommand->connectionToken = std::move(connectionToken);
5597 postCommandLocked(std::move(windowResponsiveCommand));
5598}
5599
5600/**
5601 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5602 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5603 * command entry to the command queue.
5604 */
5605void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5606 std::string reason) {
5607 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5608 if (connection.monitor) {
5609 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5610 reason.c_str());
5611 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5612 if (!pid.has_value()) {
5613 ALOGE("Could not find unresponsive monitor for connection %s",
5614 connection.inputChannel->getName().c_str());
5615 return;
5616 }
5617 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5618 return;
5619 }
5620 // If not a monitor, must be a window
5621 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5622 reason.c_str());
5623 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5624}
5625
5626/**
5627 * Tell the policy that a connection has become responsive so that it can stop ANR.
5628 */
5629void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5630 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5631 if (connection.monitor) {
5632 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5633 if (!pid.has_value()) {
5634 ALOGE("Could not find responsive monitor for connection %s",
5635 connection.inputChannel->getName().c_str());
5636 return;
5637 }
5638 sendMonitorResponsiveCommandLocked(pid.value());
5639 return;
5640 }
5641 // If not a monitor, must be a window
5642 sendWindowResponsiveCommandLocked(connectionToken);
5643}
5644
Michael Wrightd02c5b62014-02-10 15:10:22 -08005645bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005646 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005647 KeyEntry& keyEntry, bool handled) {
5648 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005649 if (!handled) {
5650 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005651 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005652 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005653 return false;
5654 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005655
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005656 // Get the fallback key state.
5657 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005658 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005659 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005660 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005661 connection->inputState.removeFallbackKey(originalKeyCode);
5662 }
5663
5664 if (handled || !dispatchEntry->hasForegroundTarget()) {
5665 // If the application handles the original key for which we previously
5666 // generated a fallback or if the window is not a foreground window,
5667 // then cancel the associated fallback key, if any.
5668 if (fallbackKeyCode != -1) {
5669 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005670#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005671 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005672 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005673 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005674#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005675 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005676 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005677
5678 mLock.unlock();
5679
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005680 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005681 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005682
5683 mLock.lock();
5684
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005685 // Cancel the fallback key.
5686 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005687 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005688 "application handled the original non-fallback key "
5689 "or is no longer a foreground target, "
5690 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005691 options.keyCode = fallbackKeyCode;
5692 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005693 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005694 connection->inputState.removeFallbackKey(originalKeyCode);
5695 }
5696 } else {
5697 // If the application did not handle a non-fallback key, first check
5698 // that we are in a good state to perform unhandled key event processing
5699 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005700 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005701 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005702#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005703 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005704 "since this is not an initial down. "
5705 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005706 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005707#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005708 return false;
5709 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005710
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005711 // Dispatch the unhandled key to the policy.
5712#if DEBUG_OUTBOUND_EVENT_DETAILS
5713 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005714 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005715 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005716#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005717 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005718
5719 mLock.unlock();
5720
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005721 bool fallback =
5722 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005723 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005724
5725 mLock.lock();
5726
5727 if (connection->status != Connection::STATUS_NORMAL) {
5728 connection->inputState.removeFallbackKey(originalKeyCode);
5729 return false;
5730 }
5731
5732 // Latch the fallback keycode for this key on an initial down.
5733 // The fallback keycode cannot change at any other point in the lifecycle.
5734 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005735 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005736 fallbackKeyCode = event.getKeyCode();
5737 } else {
5738 fallbackKeyCode = AKEYCODE_UNKNOWN;
5739 }
5740 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5741 }
5742
5743 ALOG_ASSERT(fallbackKeyCode != -1);
5744
5745 // Cancel the fallback key if the policy decides not to send it anymore.
5746 // We will continue to dispatch the key to the policy but we will no
5747 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005748 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5749 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005750#if DEBUG_OUTBOUND_EVENT_DETAILS
5751 if (fallback) {
5752 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005753 "as a fallback for %d, but on the DOWN it had requested "
5754 "to send %d instead. Fallback canceled.",
5755 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005756 } else {
5757 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005758 "but on the DOWN it had requested to send %d. "
5759 "Fallback canceled.",
5760 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005761 }
5762#endif
5763
5764 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5765 "canceling fallback, policy no longer desires it");
5766 options.keyCode = fallbackKeyCode;
5767 synthesizeCancelationEventsForConnectionLocked(connection, options);
5768
5769 fallback = false;
5770 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005771 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005772 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005773 }
5774 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005775
5776#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005777 {
5778 std::string msg;
5779 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5780 connection->inputState.getFallbackKeys();
5781 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005782 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005783 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005784 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005785 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005786 }
5787#endif
5788
5789 if (fallback) {
5790 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005791 keyEntry.eventTime = event.getEventTime();
5792 keyEntry.deviceId = event.getDeviceId();
5793 keyEntry.source = event.getSource();
5794 keyEntry.displayId = event.getDisplayId();
5795 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5796 keyEntry.keyCode = fallbackKeyCode;
5797 keyEntry.scanCode = event.getScanCode();
5798 keyEntry.metaState = event.getMetaState();
5799 keyEntry.repeatCount = event.getRepeatCount();
5800 keyEntry.downTime = event.getDownTime();
5801 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005802
5803#if DEBUG_OUTBOUND_EVENT_DETAILS
5804 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005805 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005806 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005807#endif
5808 return true; // restart the event
5809 } else {
5810#if DEBUG_OUTBOUND_EVENT_DETAILS
5811 ALOGD("Unhandled key event: No fallback key.");
5812#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005813
5814 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005815 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005816 }
5817 }
5818 return false;
5819}
5820
5821bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005822 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005823 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005824 return false;
5825}
5826
5827void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5828 mLock.unlock();
5829
Sean Stoutb4e0a592021-02-23 07:34:53 -08005830 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType,
5831 commandEntry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005832
5833 mLock.lock();
5834}
5835
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005836void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5837 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005838 // TODO Write some statistics about how long we spend waiting.
5839}
5840
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005841/**
5842 * Report the touch event latency to the statsd server.
5843 * Input events are reported for statistics if:
5844 * - This is a touchscreen event
5845 * - InputFilter is not enabled
5846 * - Event is not injected or synthesized
5847 *
5848 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5849 * from getting aggregated with the "old" data.
5850 */
5851void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5852 REQUIRES(mLock) {
5853 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5854 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5855 if (!reportForStatistics) {
5856 return;
5857 }
5858
5859 if (mTouchStatistics.shouldReport()) {
5860 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5861 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5862 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5863 mTouchStatistics.reset();
5864 }
5865 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5866 mTouchStatistics.addValue(latencyMicros);
5867}
5868
Michael Wrightd02c5b62014-02-10 15:10:22 -08005869void InputDispatcher::traceInboundQueueLengthLocked() {
5870 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005871 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005872 }
5873}
5874
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005875void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005876 if (ATRACE_ENABLED()) {
5877 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005878 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005879 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005880 }
5881}
5882
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005883void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005884 if (ATRACE_ENABLED()) {
5885 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005886 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005887 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005888 }
5889}
5890
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005891void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005892 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005893
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005894 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005895 dumpDispatchStateLocked(dump);
5896
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005897 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005898 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005899 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005900 }
5901}
5902
5903void InputDispatcher::monitor() {
5904 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005905 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005906 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005907 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005908}
5909
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005910/**
5911 * Wake up the dispatcher and wait until it processes all events and commands.
5912 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5913 * this method can be safely called from any thread, as long as you've ensured that
5914 * the work you are interested in completing has already been queued.
5915 */
5916bool InputDispatcher::waitForIdle() {
5917 /**
5918 * Timeout should represent the longest possible time that a device might spend processing
5919 * events and commands.
5920 */
5921 constexpr std::chrono::duration TIMEOUT = 100ms;
5922 std::unique_lock lock(mLock);
5923 mLooper->wake();
5924 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5925 return result == std::cv_status::no_timeout;
5926}
5927
Vishnu Naire798b472020-07-23 13:52:21 -07005928/**
5929 * Sets focus to the window identified by the token. This must be called
5930 * after updating any input window handles.
5931 *
5932 * Params:
5933 * request.token - input channel token used to identify the window that should gain focus.
5934 * request.focusedToken - the token that the caller expects currently to be focused. If the
5935 * specified token does not match the currently focused window, this request will be dropped.
5936 * If the specified focused token matches the currently focused window, the call will succeed.
5937 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5938 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5939 * when requesting the focus change. This determines which request gets
5940 * precedence if there is a focus change request from another source such as pointer down.
5941 */
Vishnu Nair958da932020-08-21 17:12:37 -07005942void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5943 { // acquire lock
5944 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005945 std::optional<FocusResolver::FocusChanges> changes =
5946 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
5947 if (changes) {
5948 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07005949 }
5950 } // release lock
5951 // Wake up poll loop since it may need to make new input dispatching choices.
5952 mLooper->wake();
5953}
5954
Vishnu Nairc519ff72021-01-21 08:23:08 -08005955void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
5956 if (changes.oldFocus) {
5957 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005958 if (focusedInputChannel) {
5959 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5960 "focus left window");
5961 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005962 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005963 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005964 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08005965 if (changes.newFocus) {
5966 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005967 }
5968
Prabir Pradhan99987712020-11-10 18:43:05 -08005969 // If a window has pointer capture, then it must have focus. We need to ensure that this
5970 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
5971 // If the window loses focus before it loses pointer capture, then the window can be in a state
5972 // where it has pointer capture but not focus, violating the contract. Therefore we must
5973 // dispatch the pointer capture event before the focus event. Since focus events are added to
5974 // the front of the queue (above), we add the pointer capture event to the front of the queue
5975 // after the focus events are added. This ensures the pointer capture event ends up at the
5976 // front.
5977 disablePointerCaptureForcedLocked();
5978
Vishnu Nairc519ff72021-01-21 08:23:08 -08005979 if (mFocusedDisplayId == changes.displayId) {
5980 notifyFocusChangedLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005981 }
5982}
Vishnu Nair958da932020-08-21 17:12:37 -07005983
Prabir Pradhan99987712020-11-10 18:43:05 -08005984void InputDispatcher::disablePointerCaptureForcedLocked() {
5985 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
5986 return;
5987 }
5988
5989 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
5990
5991 if (mFocusedWindowRequestedPointerCapture) {
5992 mFocusedWindowRequestedPointerCapture = false;
5993 setPointerCaptureLocked(false);
5994 }
5995
5996 if (!mWindowTokenWithPointerCapture) {
5997 // No need to send capture changes because no window has capture.
5998 return;
5999 }
6000
6001 if (mPendingEvent != nullptr) {
6002 // Move the pending event to the front of the queue. This will give the chance
6003 // for the pending event to be dropped if it is a captured event.
6004 mInboundQueue.push_front(mPendingEvent);
6005 mPendingEvent = nullptr;
6006 }
6007
6008 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
6009 false /* hasCapture */);
6010 mInboundQueue.push_front(std::move(entry));
6011}
6012
Prabir Pradhan99987712020-11-10 18:43:05 -08006013void InputDispatcher::setPointerCaptureLocked(bool enabled) {
6014 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
6015 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
6016 commandEntry->enabled = enabled;
6017 postCommandLocked(std::move(commandEntry));
6018}
6019
6020void InputDispatcher::doSetPointerCaptureLockedInterruptible(
6021 android::inputdispatcher::CommandEntry* commandEntry) {
6022 mLock.unlock();
6023
6024 mPolicy->setPointerCapture(commandEntry->enabled);
6025
6026 mLock.lock();
6027}
6028
Garfield Tane84e6f92019-08-29 17:28:41 -07006029} // namespace android::inputdispatcher