blob: 6d9190cce895047ca229a12355c7c91fb042fee1 [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
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700755 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700756 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700757 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700758 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700759 resetPendingAppSwitchLocked(true);
760 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700761 } else if (dropReason == DropReason::NOT_DROPPED) {
762 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700763 }
764 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700765 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700766 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700767 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700768 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
769 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700770 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700771 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700772 break;
773 }
774
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700775 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700776 std::shared_ptr<MotionEntry> motionEntry =
777 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700778 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
779 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800780 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700781 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700782 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700783 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700784 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
785 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700786 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700787 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700788 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800789 }
Chris Yef59a2f42020-10-16 12:55:26 -0700790
791 case EventEntry::Type::SENSOR: {
792 std::shared_ptr<SensorEntry> sensorEntry =
793 std::static_pointer_cast<SensorEntry>(mPendingEvent);
794 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
795 dropReason = DropReason::APP_SWITCH;
796 }
797 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
798 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
799 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
800 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
801 dropReason = DropReason::STALE;
802 }
803 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
804 done = true;
805 break;
806 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800807 }
808
809 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700810 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700811 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800812 }
Michael Wright3a981722015-06-10 15:26:13 +0100813 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800814
815 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700816 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800817 }
818}
819
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700820/**
821 * Return true if the events preceding this incoming motion event should be dropped
822 * Return false otherwise (the default behaviour)
823 */
824bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700825 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700826 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700827
828 // Optimize case where the current application is unresponsive and the user
829 // decides to touch a window in a different application.
830 // If the application takes too long to catch up then we drop all events preceding
831 // the touch into the other window.
832 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700833 int32_t displayId = motionEntry.displayId;
834 int32_t x = static_cast<int32_t>(
835 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
836 int32_t y = static_cast<int32_t>(
837 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
838 sp<InputWindowHandle> touchedWindowHandle =
839 findTouchedWindowAtLocked(displayId, x, y, nullptr);
840 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700841 touchedWindowHandle->getApplicationToken() !=
842 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700843 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700844 ALOGI("Pruning input queue because user touched a different application while waiting "
845 "for %s",
846 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700847 return true;
848 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700849
850 // Alternatively, maybe there's a gesture monitor that could handle this event
851 std::vector<TouchedMonitor> gestureMonitors =
852 findTouchedGestureMonitorsLocked(displayId, {});
853 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
854 sp<Connection> connection =
855 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000856 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700857 // This monitor could take more input. Drop all events preceding this
858 // event, so that gesture monitor could get a chance to receive the stream
859 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
860 "responsive gesture monitor that may handle the event",
861 mAwaitedFocusedApplication->getName().c_str());
862 return true;
863 }
864 }
865 }
866
867 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
868 // yet been processed by some connections, the dispatcher will wait for these motion
869 // events to be processed before dispatching the key event. This is because these motion events
870 // may cause a new window to be launched, which the user might expect to receive focus.
871 // To prevent waiting forever for such events, just send the key to the currently focused window
872 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
873 ALOGD("Received a new pointer down event, stop waiting for events to process and "
874 "just send the pending key event to the focused window.");
875 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700876 }
877 return false;
878}
879
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700880bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700881 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700882 mInboundQueue.push_back(std::move(newEntry));
883 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800884 traceInboundQueueLengthLocked();
885
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700886 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700887 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700888 // Optimize app switch latency.
889 // If the application takes too long to catch up then we drop all events preceding
890 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700891 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700892 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700893 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700894 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700895 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700896 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800897#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700898 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800899#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700900 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700901 mAppSwitchSawKeyDown = false;
902 needWake = true;
903 }
904 }
905 }
906 break;
907 }
908
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700909 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700910 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
911 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700912 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800913 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700914 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800915 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100916 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700917 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
918 break;
919 }
920 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -0800921 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -0700922 case EventEntry::Type::SENSOR:
Prabir Pradhan99987712020-11-10 18:43:05 -0800923 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700924 // nothing to do
925 break;
926 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800927 }
928
929 return needWake;
930}
931
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700932void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -0700933 // Do not store sensor event in recent queue to avoid flooding the queue.
934 if (entry->type != EventEntry::Type::SENSOR) {
935 mRecentQueue.push_back(entry);
936 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700937 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700938 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800939 }
940}
941
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700942sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700943 int32_t y, TouchState* touchState,
944 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700945 bool addPortalWindows) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700946 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
947 LOG_ALWAYS_FATAL(
948 "Must provide a valid touch state if adding portal windows or outside targets");
949 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800950 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700951 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800952 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800953 const InputWindowInfo* windowInfo = windowHandle->getInfo();
954 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100955 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800956
957 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100958 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
959 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
960 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800961 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800962 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700963 if (portalToDisplayId != ADISPLAY_ID_NONE &&
964 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800965 if (addPortalWindows) {
966 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700967 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800968 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700969 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700970 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800971 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800972 // Found window.
973 return windowHandle;
974 }
975 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800976
Michael Wright44753b12020-07-08 13:48:11 +0100977 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700978 touchState->addOrUpdateWindow(windowHandle,
979 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
980 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800981 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800982 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800983 }
984 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700985 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800986}
987
Garfield Tane84e6f92019-08-29 17:28:41 -0700988std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700989 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000990 std::vector<TouchedMonitor> touchedMonitors;
991
992 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
993 addGestureMonitors(monitors, touchedMonitors);
994 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
995 const InputWindowInfo* windowInfo = portalWindow->getInfo();
996 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700997 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
998 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000999 }
1000 return touchedMonitors;
1001}
1002
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001003void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001004 const char* reason;
1005 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001006 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -08001007#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001008 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001009#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001010 reason = "inbound event was dropped because the policy consumed it";
1011 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001012 case DropReason::DISABLED:
1013 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001014 ALOGI("Dropped event because input dispatch is disabled.");
1015 }
1016 reason = "inbound event was dropped because input dispatch is disabled";
1017 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001018 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001019 ALOGI("Dropped event because of pending overdue app switch.");
1020 reason = "inbound event was dropped because of pending overdue app switch";
1021 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001022 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001023 ALOGI("Dropped event because the current application is not responding and the user "
1024 "has started interacting with a different application.");
1025 reason = "inbound event was dropped because the current application is not responding "
1026 "and the user has started interacting with a different application";
1027 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001028 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001029 ALOGI("Dropped event because it is stale.");
1030 reason = "inbound event was dropped because it is stale";
1031 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001032 case DropReason::NO_POINTER_CAPTURE:
1033 ALOGI("Dropped event because there is no window with Pointer Capture.");
1034 reason = "inbound event was dropped because there is no window with Pointer Capture";
1035 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001036 case DropReason::NOT_DROPPED: {
1037 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001038 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001039 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001040 }
1041
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001042 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001043 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001044 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1045 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001046 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001047 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001048 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001049 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1050 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001051 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1052 synthesizeCancelationEventsForAllConnectionsLocked(options);
1053 } else {
1054 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1055 synthesizeCancelationEventsForAllConnectionsLocked(options);
1056 }
1057 break;
1058 }
Chris Yef59a2f42020-10-16 12:55:26 -07001059 case EventEntry::Type::SENSOR: {
1060 break;
1061 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001062 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1063 break;
1064 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001065 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001066 case EventEntry::Type::CONFIGURATION_CHANGED:
1067 case EventEntry::Type::DEVICE_RESET: {
Chris Yef59a2f42020-10-16 12:55:26 -07001068 LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001069 break;
1070 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001071 }
1072}
1073
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001074static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001075 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1076 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001077}
1078
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001079bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1080 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1081 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1082 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001083}
1084
1085bool InputDispatcher::isAppSwitchPendingLocked() {
1086 return mAppSwitchDueTime != LONG_LONG_MAX;
1087}
1088
1089void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1090 mAppSwitchDueTime = LONG_LONG_MAX;
1091
1092#if DEBUG_APP_SWITCH
1093 if (handled) {
1094 ALOGD("App switch has arrived.");
1095 } else {
1096 ALOGD("App switch was abandoned.");
1097 }
1098#endif
1099}
1100
Michael Wrightd02c5b62014-02-10 15:10:22 -08001101bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001102 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001103}
1104
1105bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001106 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001107 return false;
1108 }
1109
1110 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001111 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001112 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001113 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001114 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001115
1116 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001117 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001118 return true;
1119}
1120
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001121void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1122 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001123}
1124
1125void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001126 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001127 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001128 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001129 releaseInboundEventLocked(entry);
1130 }
1131 traceInboundQueueLengthLocked();
1132}
1133
1134void InputDispatcher::releasePendingEventLocked() {
1135 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001136 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001137 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001138 }
1139}
1140
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001141void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001142 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001143 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001144#if DEBUG_DISPATCH_CYCLE
1145 ALOGD("Injected inbound event was dropped.");
1146#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001147 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001148 }
1149 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001150 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001151 }
1152 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001153}
1154
1155void InputDispatcher::resetKeyRepeatLocked() {
1156 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001157 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001158 }
1159}
1160
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001161std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1162 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001163
Michael Wright2e732952014-09-24 13:26:59 -07001164 uint32_t policyFlags = entry->policyFlags &
1165 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001166
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001167 std::shared_ptr<KeyEntry> newEntry =
1168 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1169 entry->source, entry->displayId, policyFlags, entry->action,
1170 entry->flags, entry->keyCode, entry->scanCode,
1171 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001172
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001173 newEntry->syntheticRepeat = true;
1174 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001175 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001176 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001177}
1178
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001179bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001180 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001181#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001182 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001183#endif
1184
1185 // Reset key repeating in case a keyboard device was added or removed or something.
1186 resetKeyRepeatLocked();
1187
1188 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001189 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1190 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001191 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001192 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001193 return true;
1194}
1195
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001196bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1197 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001198#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001199 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1200 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001201#endif
1202
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001203 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001204 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001205 synthesizeCancelationEventsForAllConnectionsLocked(options);
1206 return true;
1207}
1208
Vishnu Nairad321cd2020-08-20 16:40:21 -07001209void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001210 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001211 if (mPendingEvent != nullptr) {
1212 // Move the pending event to the front of the queue. This will give the chance
1213 // for the pending event to get dispatched to the newly focused window
1214 mInboundQueue.push_front(mPendingEvent);
1215 mPendingEvent = nullptr;
1216 }
1217
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001218 std::unique_ptr<FocusEntry> focusEntry =
1219 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1220 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001221
1222 // This event should go to the front of the queue, but behind all other focus events
1223 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001224 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001225 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001226 [](const std::shared_ptr<EventEntry>& event) {
1227 return event->type == EventEntry::Type::FOCUS;
1228 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001229
1230 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001231 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001232}
1233
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001234void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001235 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001236 if (channel == nullptr) {
1237 return; // Window has gone away
1238 }
1239 InputTarget target;
1240 target.inputChannel = channel;
1241 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1242 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001243 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1244 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001245 std::string reason = std::string("reason=").append(entry->reason);
1246 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001247 dispatchEventLocked(currentTime, entry, {target});
1248}
1249
Prabir Pradhan99987712020-11-10 18:43:05 -08001250void InputDispatcher::dispatchPointerCaptureChangedLocked(
1251 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1252 DropReason& dropReason) {
1253 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan167e6d92021-02-04 16:18:17 -08001254 if (entry->pointerCaptureEnabled && haveWindowWithPointerCapture) {
1255 LOG_ALWAYS_FATAL("Pointer Capture has already been enabled for the window.");
1256 }
1257 if (!entry->pointerCaptureEnabled && !haveWindowWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001258 // Pointer capture was already forcefully disabled because of focus change.
1259 dropReason = DropReason::NOT_DROPPED;
1260 return;
1261 }
1262
1263 // Set drop reason for early returns
1264 dropReason = DropReason::NO_POINTER_CAPTURE;
1265
1266 sp<IBinder> token;
1267 if (entry->pointerCaptureEnabled) {
1268 // Enable Pointer Capture
1269 if (!mFocusedWindowRequestedPointerCapture) {
1270 // This can happen if a window requests capture and immediately releases capture.
1271 ALOGW("No window requested Pointer Capture.");
1272 return;
1273 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08001274 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001275 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1276 mWindowTokenWithPointerCapture = token;
1277 } else {
1278 // Disable Pointer Capture
1279 token = mWindowTokenWithPointerCapture;
1280 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001281 if (mFocusedWindowRequestedPointerCapture) {
1282 mFocusedWindowRequestedPointerCapture = false;
1283 setPointerCaptureLocked(false);
1284 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001285 }
1286
1287 auto channel = getInputChannelLocked(token);
1288 if (channel == nullptr) {
1289 // Window has gone away, clean up Pointer Capture state.
1290 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001291 if (mFocusedWindowRequestedPointerCapture) {
1292 mFocusedWindowRequestedPointerCapture = false;
1293 setPointerCaptureLocked(false);
1294 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001295 return;
1296 }
1297 InputTarget target;
1298 target.inputChannel = channel;
1299 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1300 entry->dispatchInProgress = true;
1301 dispatchEventLocked(currentTime, entry, {target});
1302
1303 dropReason = DropReason::NOT_DROPPED;
1304}
1305
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001306bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001307 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001308 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001309 if (!entry->dispatchInProgress) {
1310 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1311 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1312 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1313 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001314 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001315 // We have seen two identical key downs in a row which indicates that the device
1316 // driver is automatically generating key repeats itself. We take note of the
1317 // repeat here, but we disable our own next key repeat timer since it is clear that
1318 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001319 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1320 // Make sure we don't get key down from a different device. If a different
1321 // device Id has same key pressed down, the new device Id will replace the
1322 // current one to hold the key repeat with repeat count reset.
1323 // In the future when got a KEY_UP on the device id, drop it and do not
1324 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001325 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1326 resetKeyRepeatLocked();
1327 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1328 } else {
1329 // Not a repeat. Save key down state in case we do see a repeat later.
1330 resetKeyRepeatLocked();
1331 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1332 }
1333 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001334 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1335 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001336 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001337#if DEBUG_INBOUND_EVENT_DETAILS
1338 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1339#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001340 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001341 resetKeyRepeatLocked();
1342 }
1343
1344 if (entry->repeatCount == 1) {
1345 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1346 } else {
1347 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1348 }
1349
1350 entry->dispatchInProgress = true;
1351
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001352 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001353 }
1354
1355 // Handle case where the policy asked us to try again later last time.
1356 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1357 if (currentTime < entry->interceptKeyWakeupTime) {
1358 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1359 *nextWakeupTime = entry->interceptKeyWakeupTime;
1360 }
1361 return false; // wait until next wakeup
1362 }
1363 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1364 entry->interceptKeyWakeupTime = 0;
1365 }
1366
1367 // Give the policy a chance to intercept the key.
1368 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1369 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001370 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001371 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001372 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001373 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001374 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001375 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001376 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001377 return false; // wait for the command to run
1378 } else {
1379 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1380 }
1381 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001382 if (*dropReason == DropReason::NOT_DROPPED) {
1383 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001384 }
1385 }
1386
1387 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001388 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001389 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001390 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1391 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001392 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001393 return true;
1394 }
1395
1396 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001397 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001398 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001399 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001400 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001401 return false;
1402 }
1403
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001404 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001405 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001406 return true;
1407 }
1408
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001409 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001410 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001411
1412 // Dispatch the key.
1413 dispatchEventLocked(currentTime, entry, inputTargets);
1414 return true;
1415}
1416
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001417void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001418#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001419 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001420 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1421 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001422 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1423 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1424 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001425#endif
1426}
1427
Chris Yef59a2f42020-10-16 12:55:26 -07001428void InputDispatcher::doNotifySensorLockedInterruptible(CommandEntry* commandEntry) {
1429 mLock.unlock();
1430
1431 const std::shared_ptr<SensorEntry>& entry = commandEntry->sensorEntry;
1432 if (entry->accuracyChanged) {
1433 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1434 }
1435 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1436 entry->hwTimestamp, entry->values);
1437 mLock.lock();
1438}
1439
1440void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, std::shared_ptr<SensorEntry> entry,
1441 DropReason* dropReason, nsecs_t* nextWakeupTime) {
1442#if DEBUG_OUTBOUND_EVENT_DETAILS
1443 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1444 "source=0x%x, sensorType=%s",
1445 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Prabir Pradhanbe05b5b2021-02-24 16:39:43 -08001446 NamedEnum::string(entry->sensorType).c_str());
Chris Yef59a2f42020-10-16 12:55:26 -07001447#endif
1448 std::unique_ptr<CommandEntry> commandEntry =
1449 std::make_unique<CommandEntry>(&InputDispatcher::doNotifySensorLockedInterruptible);
1450 commandEntry->sensorEntry = entry;
1451 postCommandLocked(std::move(commandEntry));
1452}
1453
1454bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
1455#if DEBUG_OUTBOUND_EVENT_DETAILS
1456 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
1457 NamedEnum::string(sensorType).c_str());
1458#endif
1459 { // acquire lock
1460 std::scoped_lock _l(mLock);
1461
1462 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1463 std::shared_ptr<EventEntry> entry = *it;
1464 if (entry->type == EventEntry::Type::SENSOR) {
1465 it = mInboundQueue.erase(it);
1466 releaseInboundEventLocked(entry);
1467 }
1468 }
1469 }
1470 return true;
1471}
1472
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001473bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001474 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001475 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001476 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001477 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001478 entry->dispatchInProgress = true;
1479
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001480 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001481 }
1482
1483 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001484 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001485 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001486 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1487 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001488 return true;
1489 }
1490
1491 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1492
1493 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001494 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001495
1496 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001497 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001498 if (isPointerEvent) {
1499 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001500 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001501 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001502 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001503 } else {
1504 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001505 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001506 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001507 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001508 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001509 return false;
1510 }
1511
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001512 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001513 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001514 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1515 return true;
1516 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001517 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001518 CancelationOptions::Mode mode(isPointerEvent
1519 ? CancelationOptions::CANCEL_POINTER_EVENTS
1520 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1521 CancelationOptions options(mode, "input event injection failed");
1522 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001523 return true;
1524 }
1525
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001526 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001527 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001528
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001529 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001530 std::unordered_map<int32_t, TouchState>::iterator it =
1531 mTouchStatesByDisplay.find(entry->displayId);
1532 if (it != mTouchStatesByDisplay.end()) {
1533 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001534 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001535 // The event has gone through these portal windows, so we add monitoring targets of
1536 // the corresponding displays as well.
1537 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001538 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001539 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001540 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001541 }
1542 }
1543 }
1544 }
1545
Michael Wrightd02c5b62014-02-10 15:10:22 -08001546 // Dispatch the motion.
1547 if (conflictingPointerActions) {
1548 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001549 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001550 synthesizeCancelationEventsForAllConnectionsLocked(options);
1551 }
1552 dispatchEventLocked(currentTime, entry, inputTargets);
1553 return true;
1554}
1555
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001556void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001557#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001558 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001559 ", policyFlags=0x%x, "
1560 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1561 "metaState=0x%x, buttonState=0x%x,"
1562 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001563 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1564 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1565 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001566
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001567 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001568 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001569 "x=%f, y=%f, pressure=%f, size=%f, "
1570 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1571 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001572 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1573 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1574 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1575 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1576 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1577 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1578 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1579 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1580 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1581 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001582 }
1583#endif
1584}
1585
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001586void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1587 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001588 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001589 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001590#if DEBUG_DISPATCH_CYCLE
1591 ALOGD("dispatchEventToCurrentInputTargets");
1592#endif
1593
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001594 updateInteractionTokensLocked(*eventEntry, inputTargets);
1595
Michael Wrightd02c5b62014-02-10 15:10:22 -08001596 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1597
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001598 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001599
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001600 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001601 sp<Connection> connection =
1602 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001603 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001604 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001606 if (DEBUG_FOCUS) {
1607 ALOGD("Dropping event delivery to target with channel '%s' because it "
1608 "is no longer registered with the input dispatcher.",
1609 inputTarget.inputChannel->getName().c_str());
1610 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001611 }
1612 }
1613}
1614
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001615void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1616 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1617 // If the policy decides to close the app, we will get a channel removal event via
1618 // unregisterInputChannel, and will clean up the connection that way. We are already not
1619 // sending new pointers to the connection when it blocked, but focused events will continue to
1620 // pile up.
1621 ALOGW("Canceling events for %s because it is unresponsive",
1622 connection->inputChannel->getName().c_str());
1623 if (connection->status == Connection::STATUS_NORMAL) {
1624 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1625 "application not responding");
1626 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001627 }
1628}
1629
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001630void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001631 if (DEBUG_FOCUS) {
1632 ALOGD("Resetting ANR timeouts.");
1633 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001634
1635 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001636 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001637 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001638}
1639
Tiger Huang721e26f2018-07-24 22:26:19 +08001640/**
1641 * Get the display id that the given event should go to. If this event specifies a valid display id,
1642 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1643 * Focused display is the display that the user most recently interacted with.
1644 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001645int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001646 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001647 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001648 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001649 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1650 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001651 break;
1652 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001653 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001654 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1655 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001656 break;
1657 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001658 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001659 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001660 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001661 case EventEntry::Type::DEVICE_RESET:
1662 case EventEntry::Type::SENSOR: {
1663 ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001664 return ADISPLAY_ID_NONE;
1665 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001666 }
1667 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1668}
1669
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001670bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1671 const char* focusedWindowName) {
1672 if (mAnrTracker.empty()) {
1673 // already processed all events that we waited for
1674 mKeyIsWaitingForEventsTimeout = std::nullopt;
1675 return false;
1676 }
1677
1678 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1679 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001680 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001681 mKeyIsWaitingForEventsTimeout = currentTime +
1682 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1683 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001684 return true;
1685 }
1686
1687 // We still have pending events, and already started the timer
1688 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1689 return true; // Still waiting
1690 }
1691
1692 // Waited too long, and some connection still hasn't processed all motions
1693 // Just send the key to the focused window
1694 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1695 focusedWindowName);
1696 mKeyIsWaitingForEventsTimeout = std::nullopt;
1697 return false;
1698}
1699
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001700InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1701 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1702 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001703 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001704
Tiger Huang721e26f2018-07-24 22:26:19 +08001705 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001706 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001707 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001708 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1709
Michael Wrightd02c5b62014-02-10 15:10:22 -08001710 // If there is no currently focused window and no focused application
1711 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001712 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1713 ALOGI("Dropping %s event because there is no focused window or focused application in "
1714 "display %" PRId32 ".",
Chris Yef59a2f42020-10-16 12:55:26 -07001715 NamedEnum::string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001716 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001717 }
1718
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001719 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1720 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1721 // start interacting with another application via touch (app switch). This code can be removed
1722 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1723 // an app is expected to have a focused window.
1724 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1725 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1726 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001727 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1728 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1729 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001730 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001731 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001732 ALOGW("Waiting because no window has focus but %s may eventually add a "
1733 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001734 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001735 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001736 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001737 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1738 // Already raised ANR. Drop the event
1739 ALOGE("Dropping %s event because there is no focused window",
Chris Yef59a2f42020-10-16 12:55:26 -07001740 NamedEnum::string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001741 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001742 } else {
1743 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001744 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001745 }
1746 }
1747
1748 // we have a valid, non-null focused window
1749 resetNoFocusedWindowTimeoutLocked();
1750
Michael Wrightd02c5b62014-02-10 15:10:22 -08001751 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001752 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001753 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001754 }
1755
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001756 if (focusedWindowHandle->getInfo()->paused) {
1757 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001758 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001759 }
1760
1761 // If the event is a key event, then we must wait for all previous events to
1762 // complete before delivering it because previous events may have the
1763 // side-effect of transferring focus to a different window and we want to
1764 // ensure that the following keys are sent to the new window.
1765 //
1766 // Suppose the user touches a button in a window then immediately presses "A".
1767 // If the button causes a pop-up window to appear then we want to ensure that
1768 // the "A" key is delivered to the new pop-up window. This is because users
1769 // often anticipate pending UI changes when typing on a keyboard.
1770 // To obtain this behavior, we must serialize key events with respect to all
1771 // prior input events.
1772 if (entry.type == EventEntry::Type::KEY) {
1773 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1774 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001775 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001776 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001777 }
1778
1779 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001780 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001781 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1782 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001783
1784 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001785 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001786}
1787
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001788/**
1789 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1790 * that are currently unresponsive.
1791 */
1792std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1793 const std::vector<TouchedMonitor>& monitors) const {
1794 std::vector<TouchedMonitor> responsiveMonitors;
1795 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1796 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1797 sp<Connection> connection = getConnectionLocked(
1798 monitor.monitor.inputChannel->getConnectionToken());
1799 if (connection == nullptr) {
1800 ALOGE("Could not find connection for monitor %s",
1801 monitor.monitor.inputChannel->getName().c_str());
1802 return false;
1803 }
1804 if (!connection->responsive) {
1805 ALOGW("Unresponsive monitor %s will not get the new gesture",
1806 connection->inputChannel->getName().c_str());
1807 return false;
1808 }
1809 return true;
1810 });
1811 return responsiveMonitors;
1812}
1813
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001814InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1815 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1816 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001817 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001818 enum InjectionPermission {
1819 INJECTION_PERMISSION_UNKNOWN,
1820 INJECTION_PERMISSION_GRANTED,
1821 INJECTION_PERMISSION_DENIED
1822 };
1823
Michael Wrightd02c5b62014-02-10 15:10:22 -08001824 // For security reasons, we defer updating the touch state until we are sure that
1825 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001826 int32_t displayId = entry.displayId;
1827 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001828 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1829
1830 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001831 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001832 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001833 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1834 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001835
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001836 // Copy current touch state into tempTouchState.
1837 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1838 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001839 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001840 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001841 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1842 mTouchStatesByDisplay.find(displayId);
1843 if (oldStateIt != mTouchStatesByDisplay.end()) {
1844 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001845 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001846 }
1847
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001848 bool isSplit = tempTouchState.split;
1849 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1850 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1851 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001852 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1853 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1854 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1855 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1856 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001857 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001858 bool wrongDevice = false;
1859 if (newGesture) {
1860 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001861 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001862 ALOGI("Dropping event because a pointer for a different device is already down "
1863 "in display %" PRId32,
1864 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001865 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001866 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001867 switchedDevice = false;
1868 wrongDevice = true;
1869 goto Failed;
1870 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001871 tempTouchState.reset();
1872 tempTouchState.down = down;
1873 tempTouchState.deviceId = entry.deviceId;
1874 tempTouchState.source = entry.source;
1875 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001876 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001877 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001878 ALOGI("Dropping move event because a pointer for a different device is already active "
1879 "in display %" PRId32,
1880 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001881 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001882 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001883 switchedDevice = false;
1884 wrongDevice = true;
1885 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001886 }
1887
1888 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1889 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1890
Garfield Tan00f511d2019-06-12 16:55:40 -07001891 int32_t x;
1892 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001893 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001894 // Always dispatch mouse events to cursor position.
1895 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001896 x = int32_t(entry.xCursorPosition);
1897 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001898 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001899 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1900 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001901 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001902 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001903 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001904 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1905 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001906
1907 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001908 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001909 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001910
Michael Wrightd02c5b62014-02-10 15:10:22 -08001911 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001912 if (newTouchedWindowHandle != nullptr &&
1913 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001914 // New window supports splitting, but we should never split mouse events.
1915 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001916 } else if (isSplit) {
1917 // New window does not support splitting but we have already split events.
1918 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001919 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920 }
1921
1922 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001923 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001924 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001925 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001926 }
1927
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001928 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1929 ALOGI("Not sending touch event to %s because it is paused",
1930 newTouchedWindowHandle->getName().c_str());
1931 newTouchedWindowHandle = nullptr;
1932 }
1933
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001934 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001935 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001936 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1937 if (!isResponsive) {
1938 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001939 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1940 newTouchedWindowHandle = nullptr;
1941 }
1942 }
1943
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001944 // Drop events that can't be trusted due to occlusion
1945 if (newTouchedWindowHandle != nullptr &&
1946 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1947 TouchOcclusionInfo occlusionInfo =
1948 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001949 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001950 if (DEBUG_TOUCH_OCCLUSION) {
1951 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1952 for (const auto& log : occlusionInfo.debugInfo) {
1953 ALOGD("%s", log.c_str());
1954 }
1955 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001956 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
1957 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1958 ALOGW("Dropping untrusted touch event due to %s/%d",
1959 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1960 newTouchedWindowHandle = nullptr;
1961 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001962 }
1963 }
1964
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001965 // Also don't send the new touch event to unresponsive gesture monitors
1966 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1967
Michael Wright3dd60e22019-03-27 22:06:44 +00001968 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1969 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001970 "(%d, %d) in display %" PRId32 ".",
1971 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001972 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001973 goto Failed;
1974 }
1975
1976 if (newTouchedWindowHandle != nullptr) {
1977 // Set target flags.
1978 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1979 if (isSplit) {
1980 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001981 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001982 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1983 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1984 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1985 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1986 }
1987
1988 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07001989 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
1990 newHoverWindowHandle = nullptr;
1991 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001992 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00001993 }
1994
1995 // Update the temporary touch state.
1996 BitSet32 pointerIds;
1997 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001998 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001999 pointerIds.markBit(pointerId);
2000 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002001 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002002 }
2003
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002004 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002005 } else {
2006 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2007
2008 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002009 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002010 if (DEBUG_FOCUS) {
2011 ALOGD("Dropping event because the pointer is not down or we previously "
2012 "dropped the pointer down event in display %" PRId32,
2013 displayId);
2014 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002015 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002016 goto Failed;
2017 }
2018
2019 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002020 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002021 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002022 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2023 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002024
2025 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002026 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002027 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002028 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2029 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002030 if (DEBUG_FOCUS) {
2031 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2032 oldTouchedWindowHandle->getName().c_str(),
2033 newTouchedWindowHandle->getName().c_str(), displayId);
2034 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002035 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002036 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2037 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2038 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002039
2040 // Make a slippery entrance into the new window.
2041 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2042 isSplit = true;
2043 }
2044
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002045 int32_t targetFlags =
2046 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002047 if (isSplit) {
2048 targetFlags |= InputTarget::FLAG_SPLIT;
2049 }
2050 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2051 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002052 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2053 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002054 }
2055
2056 BitSet32 pointerIds;
2057 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002058 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002059 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002060 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002061 }
2062 }
2063 }
2064
2065 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002066 // Let the previous window know that the hover sequence is over, unless we already did it
2067 // when dispatching it as is to newTouchedWindowHandle.
2068 if (mLastHoverWindowHandle != nullptr &&
2069 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2070 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002071#if DEBUG_HOVER
2072 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002073 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002074#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002075 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2076 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002077 }
2078
Garfield Tandf26e862020-07-01 20:18:19 -07002079 // Let the new window know that the hover sequence is starting, unless we already did it
2080 // when dispatching it as is to newTouchedWindowHandle.
2081 if (newHoverWindowHandle != nullptr &&
2082 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2083 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002084#if DEBUG_HOVER
2085 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002086 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002087#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002088 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2089 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2090 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002091 }
2092 }
2093
2094 // Check permission to inject into all touched foreground windows and ensure there
2095 // is at least one touched foreground window.
2096 {
2097 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002098 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002099 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2100 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002101 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002102 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002103 injectionPermission = INJECTION_PERMISSION_DENIED;
2104 goto Failed;
2105 }
2106 }
2107 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002108 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002109 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002110 ALOGI("Dropping event because there is no touched foreground window in display "
2111 "%" PRId32 " or gesture monitor to receive it.",
2112 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002113 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002114 goto Failed;
2115 }
2116
2117 // Permission granted to injection into all touched foreground windows.
2118 injectionPermission = INJECTION_PERMISSION_GRANTED;
2119 }
2120
2121 // Check whether windows listening for outside touches are owned by the same UID. If it is
2122 // set the policy flag that we will not reveal coordinate information to this window.
2123 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2124 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002125 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002126 if (foregroundWindowHandle) {
2127 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002128 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002129 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2130 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
2131 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002132 tempTouchState.addOrUpdateWindow(inputWindowHandle,
2133 InputTarget::FLAG_ZERO_COORDS,
2134 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002135 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002136 }
2137 }
2138 }
2139 }
2140
Michael Wrightd02c5b62014-02-10 15:10:22 -08002141 // If this is the first pointer going down and the touched window has a wallpaper
2142 // then also add the touched wallpaper windows so they are locked in for the duration
2143 // of the touch gesture.
2144 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2145 // engine only supports touch events. We would need to add a mechanism similar
2146 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2147 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2148 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002149 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002150 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07002151 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002152 getWindowHandlesLocked(displayId);
2153 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002154 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002155 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01002156 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002157 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002158 .addOrUpdateWindow(windowHandle,
2159 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2160 InputTarget::
2161 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2162 InputTarget::FLAG_DISPATCH_AS_IS,
2163 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002164 }
2165 }
2166 }
2167 }
2168
2169 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002170 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002171
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002172 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002173 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002174 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002175 }
2176
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002177 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002178 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002179 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002180 }
2181
Michael Wrightd02c5b62014-02-10 15:10:22 -08002182 // Drop the outside or hover touch windows since we will not care about them
2183 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002184 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002185
2186Failed:
2187 // Check injection permission once and for all.
2188 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002189 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002190 injectionPermission = INJECTION_PERMISSION_GRANTED;
2191 } else {
2192 injectionPermission = INJECTION_PERMISSION_DENIED;
2193 }
2194 }
2195
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002196 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2197 return injectionResult;
2198 }
2199
Michael Wrightd02c5b62014-02-10 15:10:22 -08002200 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002201 if (!wrongDevice) {
2202 if (switchedDevice) {
2203 if (DEBUG_FOCUS) {
2204 ALOGD("Conflicting pointer actions: Switched to a different device.");
2205 }
2206 *outConflictingPointerActions = true;
2207 }
2208
2209 if (isHoverAction) {
2210 // Started hovering, therefore no longer down.
2211 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002212 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002213 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2214 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002215 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002216 *outConflictingPointerActions = true;
2217 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002218 tempTouchState.reset();
2219 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2220 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2221 tempTouchState.deviceId = entry.deviceId;
2222 tempTouchState.source = entry.source;
2223 tempTouchState.displayId = displayId;
2224 }
2225 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2226 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2227 // All pointers up or canceled.
2228 tempTouchState.reset();
2229 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2230 // First pointer went down.
2231 if (oldState && oldState->down) {
2232 if (DEBUG_FOCUS) {
2233 ALOGD("Conflicting pointer actions: Down received while already down.");
2234 }
2235 *outConflictingPointerActions = true;
2236 }
2237 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2238 // One pointer went up.
2239 if (isSplit) {
2240 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2241 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002242
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002243 for (size_t i = 0; i < tempTouchState.windows.size();) {
2244 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2245 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2246 touchedWindow.pointerIds.clearBit(pointerId);
2247 if (touchedWindow.pointerIds.isEmpty()) {
2248 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2249 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002250 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002251 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002252 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002253 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002254 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002255 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002256
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002257 // Save changes unless the action was scroll in which case the temporary touch
2258 // state was only valid for this one action.
2259 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2260 if (tempTouchState.displayId >= 0) {
2261 mTouchStatesByDisplay[displayId] = tempTouchState;
2262 } else {
2263 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002264 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002265 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002266
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002267 // Update hover state.
2268 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002269 }
2270
Michael Wrightd02c5b62014-02-10 15:10:22 -08002271 return injectionResult;
2272}
2273
2274void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002275 int32_t targetFlags, BitSet32 pointerIds,
2276 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002277 std::vector<InputTarget>::iterator it =
2278 std::find_if(inputTargets.begin(), inputTargets.end(),
2279 [&windowHandle](const InputTarget& inputTarget) {
2280 return inputTarget.inputChannel->getConnectionToken() ==
2281 windowHandle->getToken();
2282 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002283
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002284 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002285
2286 if (it == inputTargets.end()) {
2287 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002288 std::shared_ptr<InputChannel> inputChannel =
2289 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002290 if (inputChannel == nullptr) {
2291 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2292 return;
2293 }
2294 inputTarget.inputChannel = inputChannel;
2295 inputTarget.flags = targetFlags;
2296 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2297 inputTargets.push_back(inputTarget);
2298 it = inputTargets.end() - 1;
2299 }
2300
2301 ALOG_ASSERT(it->flags == targetFlags);
2302 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2303
chaviw1ff3d1e2020-07-01 15:53:47 -07002304 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002305}
2306
Michael Wright3dd60e22019-03-27 22:06:44 +00002307void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002308 int32_t displayId, float xOffset,
2309 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002310 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2311 mGlobalMonitorsByDisplay.find(displayId);
2312
2313 if (it != mGlobalMonitorsByDisplay.end()) {
2314 const std::vector<Monitor>& monitors = it->second;
2315 for (const Monitor& monitor : monitors) {
2316 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002317 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002318 }
2319}
2320
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002321void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2322 float yOffset,
2323 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002324 InputTarget target;
2325 target.inputChannel = monitor.inputChannel;
2326 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002327 ui::Transform t;
2328 t.set(xOffset, yOffset);
2329 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002330 inputTargets.push_back(target);
2331}
2332
Michael Wrightd02c5b62014-02-10 15:10:22 -08002333bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002334 const InjectionState* injectionState) {
2335 if (injectionState &&
2336 (windowHandle == nullptr ||
2337 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2338 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002339 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002340 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002341 "owned by uid %d",
2342 injectionState->injectorPid, injectionState->injectorUid,
2343 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002344 } else {
2345 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002346 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002347 }
2348 return false;
2349 }
2350 return true;
2351}
2352
Robert Carrc9bf1d32020-04-13 17:21:08 -07002353/**
2354 * Indicate whether one window handle should be considered as obscuring
2355 * another window handle. We only check a few preconditions. Actually
2356 * checking the bounds is left to the caller.
2357 */
2358static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2359 const sp<InputWindowHandle>& otherHandle) {
2360 // Compare by token so cloned layers aren't counted
2361 if (haveSameToken(windowHandle, otherHandle)) {
2362 return false;
2363 }
2364 auto info = windowHandle->getInfo();
2365 auto otherInfo = otherHandle->getInfo();
2366 if (!otherInfo->visible) {
2367 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002368 } else if (otherInfo->alpha == 0 &&
2369 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2370 // Those act as if they were invisible, so we don't need to flag them.
2371 // We do want to potentially flag touchable windows even if they have 0
2372 // opacity, since they can consume touches and alter the effects of the
2373 // user interaction (eg. apps that rely on
2374 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2375 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2376 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002377 } else if (info->ownerUid == otherInfo->ownerUid) {
2378 // If ownerUid is the same we don't generate occlusion events as there
2379 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002380 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002381 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002382 return false;
2383 } else if (otherInfo->displayId != info->displayId) {
2384 return false;
2385 }
2386 return true;
2387}
2388
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002389/**
2390 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2391 * untrusted, one should check:
2392 *
2393 * 1. If result.hasBlockingOcclusion is true.
2394 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2395 * BLOCK_UNTRUSTED.
2396 *
2397 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2398 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2399 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2400 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2401 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2402 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2403 *
2404 * If neither of those is true, then it means the touch can be allowed.
2405 */
2406InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2407 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002408 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2409 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002410 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2411 TouchOcclusionInfo info;
2412 info.hasBlockingOcclusion = false;
2413 info.obscuringOpacity = 0;
2414 info.obscuringUid = -1;
2415 std::map<int32_t, float> opacityByUid;
2416 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2417 if (windowHandle == otherHandle) {
2418 break; // All future windows are below us. Exit early.
2419 }
2420 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002421 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2422 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002423 if (DEBUG_TOUCH_OCCLUSION) {
2424 info.debugInfo.push_back(
2425 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2426 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002427 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2428 // we perform the checks below to see if the touch can be propagated or not based on the
2429 // window's touch occlusion mode
2430 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2431 info.hasBlockingOcclusion = true;
2432 info.obscuringUid = otherInfo->ownerUid;
2433 info.obscuringPackage = otherInfo->packageName;
2434 break;
2435 }
2436 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2437 uint32_t uid = otherInfo->ownerUid;
2438 float opacity =
2439 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2440 // Given windows A and B:
2441 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2442 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2443 opacityByUid[uid] = opacity;
2444 if (opacity > info.obscuringOpacity) {
2445 info.obscuringOpacity = opacity;
2446 info.obscuringUid = uid;
2447 info.obscuringPackage = otherInfo->packageName;
2448 }
2449 }
2450 }
2451 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002452 if (DEBUG_TOUCH_OCCLUSION) {
2453 info.debugInfo.push_back(
2454 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2455 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002456 return info;
2457}
2458
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002459std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2460 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002461 return StringPrintf(INDENT2
2462 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2463 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2464 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2465 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002466 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002467 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002468 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002469 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2470 info->frameTop, info->frameRight, info->frameBottom,
2471 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002472 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2473 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2474 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002475}
2476
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002477bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2478 if (occlusionInfo.hasBlockingOcclusion) {
2479 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2480 occlusionInfo.obscuringUid);
2481 return false;
2482 }
2483 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2484 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2485 "%.2f, maximum allowed = %.2f)",
2486 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2487 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2488 return false;
2489 }
2490 return true;
2491}
2492
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002493bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2494 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002495 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002496 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002497 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002498 if (windowHandle == otherHandle) {
2499 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002500 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002501 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002502 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002503 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002504 return true;
2505 }
2506 }
2507 return false;
2508}
2509
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002510bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2511 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002512 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002513 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002514 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002515 if (windowHandle == otherHandle) {
2516 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002517 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002518 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002519 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002520 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002521 return true;
2522 }
2523 }
2524 return false;
2525}
2526
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002527std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002528 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002529 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002530 if (applicationHandle != nullptr) {
2531 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002532 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002533 } else {
2534 return applicationHandle->getName();
2535 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002536 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002537 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002538 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002539 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002540 }
2541}
2542
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002543void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002544 if (eventEntry.type == EventEntry::Type::FOCUS ||
2545 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED) {
2546 // Focus or pointer capture changed events are passed to apps, but do not represent user
2547 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002548 return;
2549 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002550 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002551 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002552 if (focusedWindowHandle != nullptr) {
2553 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002554 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002555#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002556 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002557#endif
2558 return;
2559 }
2560 }
2561
2562 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002563 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002564 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002565 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2566 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002567 return;
2568 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002569
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002570 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002571 eventType = USER_ACTIVITY_EVENT_TOUCH;
2572 }
2573 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002574 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002575 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002576 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2577 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002578 return;
2579 }
2580 eventType = USER_ACTIVITY_EVENT_BUTTON;
2581 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002582 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002583 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002584 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002585 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002586 case EventEntry::Type::SENSOR:
Prabir Pradhan99987712020-11-10 18:43:05 -08002587 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002588 LOG_ALWAYS_FATAL("%s events are not user activity",
Chris Yef59a2f42020-10-16 12:55:26 -07002589 NamedEnum::string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002590 break;
2591 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002592 }
2593
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002594 std::unique_ptr<CommandEntry> commandEntry =
2595 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002596 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002597 commandEntry->userActivityEventType = eventType;
Sean Stoutb4e0a592021-02-23 07:34:53 -08002598 commandEntry->displayId = displayId;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002599 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002600}
2601
2602void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002603 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002604 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002605 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002606 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002607 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002608 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002609 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002610 ATRACE_NAME(message.c_str());
2611 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002612#if DEBUG_DISPATCH_CYCLE
2613 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002614 "globalScaleFactor=%f, pointerIds=0x%x %s",
2615 connection->getInputChannelName().c_str(), inputTarget.flags,
2616 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2617 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002618#endif
2619
2620 // Skip this event if the connection status is not normal.
2621 // We don't want to enqueue additional outbound events if the connection is broken.
2622 if (connection->status != Connection::STATUS_NORMAL) {
2623#if DEBUG_DISPATCH_CYCLE
2624 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002625 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002626#endif
2627 return;
2628 }
2629
2630 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002631 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2632 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2633 "Entry type %s should not have FLAG_SPLIT",
Chris Yef59a2f42020-10-16 12:55:26 -07002634 NamedEnum::string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002635
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002636 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002637 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002638 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002639 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002640 if (!splitMotionEntry) {
2641 return; // split event was dropped
2642 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002643 if (DEBUG_FOCUS) {
2644 ALOGD("channel '%s' ~ Split motion event.",
2645 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002646 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002647 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002648 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2649 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002650 return;
2651 }
2652 }
2653
2654 // Not splitting. Enqueue dispatch entries for the event as is.
2655 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2656}
2657
2658void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002659 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002660 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002661 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002662 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002663 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002664 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002665 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002666 ATRACE_NAME(message.c_str());
2667 }
2668
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002669 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002670
2671 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002672 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002673 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002674 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002675 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002676 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002677 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002678 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002679 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002680 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002681 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002682 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002683 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002684
2685 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002686 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002687 startDispatchCycleLocked(currentTime, connection);
2688 }
2689}
2690
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002691void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002692 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002693 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002694 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002695 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002696 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2697 connection->getInputChannelName().c_str(),
2698 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002699 ATRACE_NAME(message.c_str());
2700 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002701 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002702 if (!(inputTargetFlags & dispatchMode)) {
2703 return;
2704 }
2705 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2706
2707 // This is a new event.
2708 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002709 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002710 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002711
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002712 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2713 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002714 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002715 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002716 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002717 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002718 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002719 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002720 dispatchEntry->resolvedAction = keyEntry.action;
2721 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002722
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002723 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2724 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002725#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002726 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2727 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002728#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002729 return; // skip the inconsistent event
2730 }
2731 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002732 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002733
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002734 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002735 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002736 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2737 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2738 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2739 static_cast<int32_t>(IdGenerator::Source::OTHER);
2740 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002741 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2742 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2743 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2744 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2745 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2746 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2747 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2748 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2749 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2750 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2751 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002752 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002753 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002754 }
2755 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002756 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2757 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002758#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002759 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2760 "event",
2761 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002762#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002763 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2764 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002765
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002766 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002767 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2768 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2769 }
2770 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2771 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2772 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002773
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002774 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2775 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002776#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002777 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2778 "event",
2779 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002780#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002781 return; // skip the inconsistent event
2782 }
2783
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002784 dispatchEntry->resolvedEventId =
2785 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2786 ? mIdGenerator.nextId()
2787 : motionEntry.id;
2788 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2789 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2790 ") to MotionEvent(id=0x%" PRIx32 ").",
2791 motionEntry.id, dispatchEntry->resolvedEventId);
2792 ATRACE_NAME(message.c_str());
2793 }
2794
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002795 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002796 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002797
2798 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002799 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002800 case EventEntry::Type::FOCUS:
2801 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002802 break;
2803 }
Chris Yef59a2f42020-10-16 12:55:26 -07002804 case EventEntry::Type::SENSOR: {
2805 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
2806 break;
2807 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002808 case EventEntry::Type::CONFIGURATION_CHANGED:
2809 case EventEntry::Type::DEVICE_RESET: {
2810 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chris Yef59a2f42020-10-16 12:55:26 -07002811 NamedEnum::string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002812 break;
2813 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002814 }
2815
2816 // Remember that we are waiting for this dispatch to complete.
2817 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002818 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002819 }
2820
2821 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002822 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002823 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002824}
2825
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002826/**
2827 * This function is purely for debugging. It helps us understand where the user interaction
2828 * was taking place. For example, if user is touching launcher, we will see a log that user
2829 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2830 * We will see both launcher and wallpaper in that list.
2831 * Once the interaction with a particular set of connections starts, no new logs will be printed
2832 * until the set of interacted connections changes.
2833 *
2834 * The following items are skipped, to reduce the logspam:
2835 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2836 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2837 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2838 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2839 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002840 */
2841void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2842 const std::vector<InputTarget>& targets) {
2843 // Skip ACTION_UP events, and all events other than keys and motions
2844 if (entry.type == EventEntry::Type::KEY) {
2845 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2846 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2847 return;
2848 }
2849 } else if (entry.type == EventEntry::Type::MOTION) {
2850 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2851 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2852 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2853 return;
2854 }
2855 } else {
2856 return; // Not a key or a motion
2857 }
2858
2859 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2860 std::vector<sp<Connection>> newConnections;
2861 for (const InputTarget& target : targets) {
2862 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2863 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2864 continue; // Skip windows that receive ACTION_OUTSIDE
2865 }
2866
2867 sp<IBinder> token = target.inputChannel->getConnectionToken();
2868 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002869 if (connection == nullptr) {
2870 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002871 }
2872 newConnectionTokens.insert(std::move(token));
2873 newConnections.emplace_back(connection);
2874 }
2875 if (newConnectionTokens == mInteractionConnectionTokens) {
2876 return; // no change
2877 }
2878 mInteractionConnectionTokens = newConnectionTokens;
2879
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002880 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002881 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002882 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002883 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002884 std::string message = "Interaction with: " + targetList;
2885 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002886 message += "<none>";
2887 }
2888 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2889}
2890
chaviwfd6d3512019-03-25 13:23:49 -07002891void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002892 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002893 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002894 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2895 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002896 return;
2897 }
2898
Vishnu Nairc519ff72021-01-21 08:23:08 -08002899 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002900 if (focusedToken == token) {
2901 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002902 return;
2903 }
2904
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002905 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2906 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002907 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002908 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002909}
2910
2911void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002912 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002913 if (ATRACE_ENABLED()) {
2914 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002915 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002916 ATRACE_NAME(message.c_str());
2917 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002918#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002919 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002920#endif
2921
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002922 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2923 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002925 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002926 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002927 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002928
2929 // Publish the event.
2930 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002931 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
2932 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002933 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002934 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2935 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002936
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002937 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002938 status = connection->inputPublisher
2939 .publishKeyEvent(dispatchEntry->seq,
2940 dispatchEntry->resolvedEventId, keyEntry.deviceId,
2941 keyEntry.source, keyEntry.displayId,
2942 std::move(hmac), dispatchEntry->resolvedAction,
2943 dispatchEntry->resolvedFlags, keyEntry.keyCode,
2944 keyEntry.scanCode, keyEntry.metaState,
2945 keyEntry.repeatCount, keyEntry.downTime,
2946 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002947 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002948 }
2949
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002950 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002951 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002952
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002953 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002954 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002955
chaviw82357092020-01-28 13:13:06 -08002956 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002957 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002958 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2959 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002960 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002961 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
2962 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002963 // Don't apply window scale here since we don't want scale to affect raw
2964 // coordinates. The scale will be sent back to the client and applied
2965 // later when requesting relative coordinates.
2966 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2967 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002968 }
2969 usingCoords = scaledCoords;
2970 }
2971 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002972 // We don't want the dispatch target to know.
2973 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002974 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002975 scaledCoords[i].clear();
2976 }
2977 usingCoords = scaledCoords;
2978 }
2979 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002980
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002981 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002982
2983 // Publish the motion event.
2984 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002985 .publishMotionEvent(dispatchEntry->seq,
2986 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002987 motionEntry.deviceId, motionEntry.source,
2988 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002989 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002990 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002991 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002992 motionEntry.edgeFlags, motionEntry.metaState,
2993 motionEntry.buttonState,
2994 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07002995 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002996 motionEntry.xPrecision, motionEntry.yPrecision,
2997 motionEntry.xCursorPosition,
2998 motionEntry.yCursorPosition,
2999 motionEntry.downTime, motionEntry.eventTime,
3000 motionEntry.pointerCount,
3001 motionEntry.pointerProperties, usingCoords);
3002 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003003 break;
3004 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003005
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003006 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003007 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003008 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003009 focusEntry.id,
3010 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003011 mInTouchMode);
3012 break;
3013 }
3014
Prabir Pradhan99987712020-11-10 18:43:05 -08003015 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3016 const auto& captureEntry =
3017 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3018 status = connection->inputPublisher
3019 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
3020 captureEntry.pointerCaptureEnabled);
3021 break;
3022 }
3023
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003024 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003025 case EventEntry::Type::DEVICE_RESET:
3026 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003027 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Chris Yef59a2f42020-10-16 12:55:26 -07003028 NamedEnum::string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003029 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003030 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003031 }
3032
3033 // Check the result.
3034 if (status) {
3035 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003036 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003037 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003038 "This is unexpected because the wait queue is empty, so the pipe "
3039 "should be empty and we shouldn't have any problems writing an "
3040 "event to it, status=%d",
3041 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003042 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3043 } else {
3044 // Pipe is full and we are waiting for the app to finish process some events
3045 // before sending more events to it.
3046#if DEBUG_DISPATCH_CYCLE
3047 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003048 "waiting for the application to catch up",
3049 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003050#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003051 }
3052 } else {
3053 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003054 "status=%d",
3055 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003056 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3057 }
3058 return;
3059 }
3060
3061 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003062 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3063 connection->outboundQueue.end(),
3064 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003065 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003066 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003067 if (connection->responsive) {
3068 mAnrTracker.insert(dispatchEntry->timeoutTime,
3069 connection->inputChannel->getConnectionToken());
3070 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003071 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003072 }
3073}
3074
chaviw09c8d2d2020-08-24 15:48:26 -07003075std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3076 size_t size;
3077 switch (event.type) {
3078 case VerifiedInputEvent::Type::KEY: {
3079 size = sizeof(VerifiedKeyEvent);
3080 break;
3081 }
3082 case VerifiedInputEvent::Type::MOTION: {
3083 size = sizeof(VerifiedMotionEvent);
3084 break;
3085 }
3086 }
3087 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3088 return mHmacKeyManager.sign(start, size);
3089}
3090
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003091const std::array<uint8_t, 32> InputDispatcher::getSignature(
3092 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3093 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3094 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3095 // Only sign events up and down events as the purely move events
3096 // are tied to their up/down counterparts so signing would be redundant.
3097 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3098 verifiedEvent.actionMasked = actionMasked;
3099 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003100 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003101 }
3102 return INVALID_HMAC;
3103}
3104
3105const std::array<uint8_t, 32> InputDispatcher::getSignature(
3106 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3107 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3108 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3109 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003110 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003111}
3112
Michael Wrightd02c5b62014-02-10 15:10:22 -08003113void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003114 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003115 bool handled, nsecs_t consumeTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003116#if DEBUG_DISPATCH_CYCLE
3117 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003118 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003119#endif
3120
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003121 if (connection->status == Connection::STATUS_BROKEN ||
3122 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003123 return;
3124 }
3125
3126 // Notify other system components and prepare to start the next dispatch cycle.
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003127 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled, consumeTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003128}
3129
3130void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003131 const sp<Connection>& connection,
3132 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003133#if DEBUG_DISPATCH_CYCLE
3134 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003135 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003136#endif
3137
3138 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003139 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003140 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003141 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003142 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003143
3144 // The connection appears to be unrecoverably broken.
3145 // Ignore already broken or zombie connections.
3146 if (connection->status == Connection::STATUS_NORMAL) {
3147 connection->status = Connection::STATUS_BROKEN;
3148
3149 if (notify) {
3150 // Notify other system components.
3151 onDispatchCycleBrokenLocked(currentTime, connection);
3152 }
3153 }
3154}
3155
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003156void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3157 while (!queue.empty()) {
3158 DispatchEntry* dispatchEntry = queue.front();
3159 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003160 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003161 }
3162}
3163
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003164void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003165 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003166 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003167 }
3168 delete dispatchEntry;
3169}
3170
3171int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
3172 InputDispatcher* d = static_cast<InputDispatcher*>(data);
3173
3174 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003175 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003176
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003177 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003178 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003179 "fd=%d, events=0x%x",
3180 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003181 return 0; // remove the callback
3182 }
3183
3184 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003185 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003186 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3187 if (!(events & ALOOPER_EVENT_INPUT)) {
3188 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003189 "events=0x%x",
3190 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003191 return 1;
3192 }
3193
3194 nsecs_t currentTime = now();
3195 bool gotOne = false;
3196 status_t status;
3197 for (;;) {
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003198 std::function<void(uint32_t seq, bool handled, nsecs_t consumeTime)> callback =
3199 std::bind(&InputDispatcher::finishDispatchCycleLocked, d, currentTime,
3200 connection, std::placeholders::_1, std::placeholders::_2,
3201 std::placeholders::_3);
3202
3203 status = connection->inputPublisher.receiveFinishedSignal(callback);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003204 if (status) {
3205 break;
3206 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003207 gotOne = true;
3208 }
3209 if (gotOne) {
3210 d->runCommandsLockedInterruptible();
3211 if (status == WOULD_BLOCK) {
3212 return 1;
3213 }
3214 }
3215
3216 notify = status != DEAD_OBJECT || !connection->monitor;
3217 if (notify) {
3218 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003219 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003220 }
3221 } else {
3222 // Monitor channels are never explicitly unregistered.
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003223 // We do it automatically when the remote endpoint is closed so don't warn about them.
arthurhungd352cb32020-04-28 17:09:28 +08003224 const bool stillHaveWindowHandle =
3225 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3226 nullptr;
3227 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003228 if (notify) {
3229 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003230 "events=0x%x",
3231 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003232 }
3233 }
3234
Garfield Tan15601662020-09-22 15:32:38 -07003235 // Remove the channel.
3236 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003237 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003238 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003239}
3240
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003241void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003242 const CancelationOptions& options) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003243 for (const auto& [fd, connection] : mConnectionsByFd) {
3244 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003245 }
3246}
3247
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003248void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003249 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003250 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3251 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3252}
3253
3254void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3255 const CancelationOptions& options,
3256 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3257 for (const auto& it : monitorsByDisplay) {
3258 const std::vector<Monitor>& monitors = it.second;
3259 for (const Monitor& monitor : monitors) {
3260 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003261 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003262 }
3263}
3264
Michael Wrightd02c5b62014-02-10 15:10:22 -08003265void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003266 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003267 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003268 if (connection == nullptr) {
3269 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003270 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003271
3272 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003273}
3274
3275void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3276 const sp<Connection>& connection, const CancelationOptions& options) {
3277 if (connection->status == Connection::STATUS_BROKEN) {
3278 return;
3279 }
3280
3281 nsecs_t currentTime = now();
3282
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003283 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003284 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003285
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003286 if (cancelationEvents.empty()) {
3287 return;
3288 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003289#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003290 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3291 "with reality: %s, mode=%d.",
3292 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3293 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003294#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003295
3296 InputTarget target;
3297 sp<InputWindowHandle> windowHandle =
3298 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3299 if (windowHandle != nullptr) {
3300 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003301 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003302 target.globalScaleFactor = windowInfo->globalScaleFactor;
3303 }
3304 target.inputChannel = connection->inputChannel;
3305 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3306
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003307 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003308 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003309 switch (cancelationEventEntry->type) {
3310 case EventEntry::Type::KEY: {
3311 logOutboundKeyDetails("cancel - ",
3312 static_cast<const KeyEntry&>(*cancelationEventEntry));
3313 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003314 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003315 case EventEntry::Type::MOTION: {
3316 logOutboundMotionDetails("cancel - ",
3317 static_cast<const MotionEntry&>(*cancelationEventEntry));
3318 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003319 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003320 case EventEntry::Type::FOCUS:
3321 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3322 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Chris Yef59a2f42020-10-16 12:55:26 -07003323 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003324 break;
3325 }
3326 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003327 case EventEntry::Type::DEVICE_RESET:
3328 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003329 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003330 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003331 break;
3332 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003333 }
3334
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003335 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3336 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003337 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003338
3339 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003340}
3341
Svet Ganov5d3bc372020-01-26 23:11:07 -08003342void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3343 const sp<Connection>& connection) {
3344 if (connection->status == Connection::STATUS_BROKEN) {
3345 return;
3346 }
3347
3348 nsecs_t currentTime = now();
3349
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003350 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003351 connection->inputState.synthesizePointerDownEvents(currentTime);
3352
3353 if (downEvents.empty()) {
3354 return;
3355 }
3356
3357#if DEBUG_OUTBOUND_EVENT_DETAILS
3358 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3359 connection->getInputChannelName().c_str(), downEvents.size());
3360#endif
3361
3362 InputTarget target;
3363 sp<InputWindowHandle> windowHandle =
3364 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3365 if (windowHandle != nullptr) {
3366 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003367 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003368 target.globalScaleFactor = windowInfo->globalScaleFactor;
3369 }
3370 target.inputChannel = connection->inputChannel;
3371 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3372
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003373 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003374 switch (downEventEntry->type) {
3375 case EventEntry::Type::MOTION: {
3376 logOutboundMotionDetails("down - ",
3377 static_cast<const MotionEntry&>(*downEventEntry));
3378 break;
3379 }
3380
3381 case EventEntry::Type::KEY:
3382 case EventEntry::Type::FOCUS:
3383 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003384 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003385 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3386 case EventEntry::Type::SENSOR: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003387 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003388 NamedEnum::string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003389 break;
3390 }
3391 }
3392
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003393 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3394 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003395 }
3396
3397 startDispatchCycleLocked(currentTime, connection);
3398}
3399
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003400std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3401 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003402 ALOG_ASSERT(pointerIds.value != 0);
3403
3404 uint32_t splitPointerIndexMap[MAX_POINTERS];
3405 PointerProperties splitPointerProperties[MAX_POINTERS];
3406 PointerCoords splitPointerCoords[MAX_POINTERS];
3407
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003408 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003409 uint32_t splitPointerCount = 0;
3410
3411 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003412 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003413 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003414 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003415 uint32_t pointerId = uint32_t(pointerProperties.id);
3416 if (pointerIds.hasBit(pointerId)) {
3417 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3418 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3419 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003420 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003421 splitPointerCount += 1;
3422 }
3423 }
3424
3425 if (splitPointerCount != pointerIds.count()) {
3426 // This is bad. We are missing some of the pointers that we expected to deliver.
3427 // Most likely this indicates that we received an ACTION_MOVE events that has
3428 // different pointer ids than we expected based on the previous ACTION_DOWN
3429 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3430 // in this way.
3431 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003432 "we expected there to be %d pointers. This probably means we received "
3433 "a broken sequence of pointer ids from the input device.",
3434 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003435 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003436 }
3437
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003438 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003439 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003440 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3441 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003442 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3443 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003444 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003445 uint32_t pointerId = uint32_t(pointerProperties.id);
3446 if (pointerIds.hasBit(pointerId)) {
3447 if (pointerIds.count() == 1) {
3448 // The first/last pointer went down/up.
3449 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003450 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003451 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3452 ? AMOTION_EVENT_ACTION_CANCEL
3453 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003454 } else {
3455 // A secondary pointer went down/up.
3456 uint32_t splitPointerIndex = 0;
3457 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3458 splitPointerIndex += 1;
3459 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003460 action = maskedAction |
3461 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003462 }
3463 } else {
3464 // An unrelated pointer changed.
3465 action = AMOTION_EVENT_ACTION_MOVE;
3466 }
3467 }
3468
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003469 int32_t newId = mIdGenerator.nextId();
3470 if (ATRACE_ENABLED()) {
3471 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3472 ") to MotionEvent(id=0x%" PRIx32 ").",
3473 originalMotionEntry.id, newId);
3474 ATRACE_NAME(message.c_str());
3475 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003476 std::unique_ptr<MotionEntry> splitMotionEntry =
3477 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3478 originalMotionEntry.deviceId, originalMotionEntry.source,
3479 originalMotionEntry.displayId,
3480 originalMotionEntry.policyFlags, action,
3481 originalMotionEntry.actionButton,
3482 originalMotionEntry.flags, originalMotionEntry.metaState,
3483 originalMotionEntry.buttonState,
3484 originalMotionEntry.classification,
3485 originalMotionEntry.edgeFlags,
3486 originalMotionEntry.xPrecision,
3487 originalMotionEntry.yPrecision,
3488 originalMotionEntry.xCursorPosition,
3489 originalMotionEntry.yCursorPosition,
3490 originalMotionEntry.downTime, splitPointerCount,
3491 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003492
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003493 if (originalMotionEntry.injectionState) {
3494 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003495 splitMotionEntry->injectionState->refCount += 1;
3496 }
3497
3498 return splitMotionEntry;
3499}
3500
3501void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3502#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003503 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003504#endif
3505
3506 bool needWake;
3507 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003508 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003509
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003510 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3511 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3512 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003513 } // release lock
3514
3515 if (needWake) {
3516 mLooper->wake();
3517 }
3518}
3519
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003520/**
3521 * If one of the meta shortcuts is detected, process them here:
3522 * Meta + Backspace -> generate BACK
3523 * Meta + Enter -> generate HOME
3524 * This will potentially overwrite keyCode and metaState.
3525 */
3526void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003527 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003528 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3529 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3530 if (keyCode == AKEYCODE_DEL) {
3531 newKeyCode = AKEYCODE_BACK;
3532 } else if (keyCode == AKEYCODE_ENTER) {
3533 newKeyCode = AKEYCODE_HOME;
3534 }
3535 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003536 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003537 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003538 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003539 keyCode = newKeyCode;
3540 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3541 }
3542 } else if (action == AKEY_EVENT_ACTION_UP) {
3543 // In order to maintain a consistent stream of up and down events, check to see if the key
3544 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3545 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003546 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003547 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003548 auto replacementIt = mReplacedKeys.find(replacement);
3549 if (replacementIt != mReplacedKeys.end()) {
3550 keyCode = replacementIt->second;
3551 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003552 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3553 }
3554 }
3555}
3556
Michael Wrightd02c5b62014-02-10 15:10:22 -08003557void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3558#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003559 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3560 "policyFlags=0x%x, action=0x%x, "
3561 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3562 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3563 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3564 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003565#endif
3566 if (!validateKeyEvent(args->action)) {
3567 return;
3568 }
3569
3570 uint32_t policyFlags = args->policyFlags;
3571 int32_t flags = args->flags;
3572 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003573 // InputDispatcher tracks and generates key repeats on behalf of
3574 // whatever notifies it, so repeatCount should always be set to 0
3575 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003576 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3577 policyFlags |= POLICY_FLAG_VIRTUAL;
3578 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3579 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003580 if (policyFlags & POLICY_FLAG_FUNCTION) {
3581 metaState |= AMETA_FUNCTION_ON;
3582 }
3583
3584 policyFlags |= POLICY_FLAG_TRUSTED;
3585
Michael Wright78f24442014-08-06 15:55:28 -07003586 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003587 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003588
Michael Wrightd02c5b62014-02-10 15:10:22 -08003589 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003590 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003591 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3592 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003593
Michael Wright2b3c3302018-03-02 17:19:13 +00003594 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003595 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003596 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3597 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003598 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003599 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003600
Michael Wrightd02c5b62014-02-10 15:10:22 -08003601 bool needWake;
3602 { // acquire lock
3603 mLock.lock();
3604
3605 if (shouldSendKeyToInputFilterLocked(args)) {
3606 mLock.unlock();
3607
3608 policyFlags |= POLICY_FLAG_FILTERED;
3609 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3610 return; // event was consumed by the filter
3611 }
3612
3613 mLock.lock();
3614 }
3615
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003616 std::unique_ptr<KeyEntry> newEntry =
3617 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3618 args->displayId, policyFlags, args->action, flags,
3619 keyCode, args->scanCode, metaState, repeatCount,
3620 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003621
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003622 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003623 mLock.unlock();
3624 } // release lock
3625
3626 if (needWake) {
3627 mLooper->wake();
3628 }
3629}
3630
3631bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3632 return mInputFilterEnabled;
3633}
3634
3635void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3636#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003637 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3638 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003639 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3640 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003641 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003642 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3643 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3644 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3645 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003646 for (uint32_t i = 0; i < args->pointerCount; i++) {
3647 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003648 "x=%f, y=%f, pressure=%f, size=%f, "
3649 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3650 "orientation=%f",
3651 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3652 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3653 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3654 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3655 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3656 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3657 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3658 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3659 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3660 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003661 }
3662#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003663 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3664 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003665 return;
3666 }
3667
3668 uint32_t policyFlags = args->policyFlags;
3669 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003670
3671 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003672 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003673 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3674 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003675 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003676 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003677
3678 bool needWake;
3679 { // acquire lock
3680 mLock.lock();
3681
3682 if (shouldSendMotionToInputFilterLocked(args)) {
3683 mLock.unlock();
3684
3685 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003686 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003687 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3688 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003689 args->metaState, args->buttonState, args->classification, transform,
3690 args->xPrecision, args->yPrecision, args->xCursorPosition,
3691 args->yCursorPosition, args->downTime, args->eventTime,
3692 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003693
3694 policyFlags |= POLICY_FLAG_FILTERED;
3695 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3696 return; // event was consumed by the filter
3697 }
3698
3699 mLock.lock();
3700 }
3701
3702 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003703 std::unique_ptr<MotionEntry> newEntry =
3704 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3705 args->source, args->displayId, policyFlags,
3706 args->action, args->actionButton, args->flags,
3707 args->metaState, args->buttonState,
3708 args->classification, args->edgeFlags,
3709 args->xPrecision, args->yPrecision,
3710 args->xCursorPosition, args->yCursorPosition,
3711 args->downTime, args->pointerCount,
3712 args->pointerProperties, args->pointerCoords, 0, 0);
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
Chris Yef59a2f42020-10-16 12:55:26 -07003723void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
3724#if DEBUG_INBOUND_EVENT_DETAILS
3725 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3726 " sensorType=%s",
3727 args->id, args->eventTime, args->deviceId, args->source,
3728 NamedEnum::string(args->sensorType).c_str());
3729#endif
3730
3731 bool needWake;
3732 { // acquire lock
3733 mLock.lock();
3734
3735 // Just enqueue a new sensor event.
3736 std::unique_ptr<SensorEntry> newEntry =
3737 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
3738 args->source, 0 /* policyFlags*/, args->hwTimestamp,
3739 args->sensorType, args->accuracy,
3740 args->accuracyChanged, args->values);
3741
3742 needWake = enqueueInboundEventLocked(std::move(newEntry));
3743 mLock.unlock();
3744 } // release lock
3745
3746 if (needWake) {
3747 mLooper->wake();
3748 }
3749}
3750
Chris Yefb552902021-02-03 17:18:37 -08003751void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
3752#if DEBUG_INBOUND_EVENT_DETAILS
3753 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
3754 args->deviceId, args->isOn);
3755#endif
3756 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
3757}
3758
Michael Wrightd02c5b62014-02-10 15:10:22 -08003759bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003760 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003761}
3762
3763void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3764#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003765 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003766 "switchMask=0x%08x",
3767 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003768#endif
3769
3770 uint32_t policyFlags = args->policyFlags;
3771 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003772 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003773}
3774
3775void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3776#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003777 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3778 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003779#endif
3780
3781 bool needWake;
3782 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003783 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003784
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003785 std::unique_ptr<DeviceResetEntry> newEntry =
3786 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3787 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003788 } // release lock
3789
3790 if (needWake) {
3791 mLooper->wake();
3792 }
3793}
3794
Prabir Pradhan7e186182020-11-10 13:56:45 -08003795void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3796#if DEBUG_INBOUND_EVENT_DETAILS
3797 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3798 args->enabled ? "true" : "false");
3799#endif
3800
Prabir Pradhan99987712020-11-10 18:43:05 -08003801 bool needWake;
3802 { // acquire lock
3803 std::scoped_lock _l(mLock);
3804 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
3805 args->enabled);
3806 needWake = enqueueInboundEventLocked(std::move(entry));
3807 } // release lock
3808
3809 if (needWake) {
3810 mLooper->wake();
3811 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003812}
3813
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003814InputEventInjectionResult InputDispatcher::injectInputEvent(
3815 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3816 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003817#if DEBUG_INBOUND_EVENT_DETAILS
3818 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003819 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3820 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003821#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003822 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003823
3824 policyFlags |= POLICY_FLAG_INJECTED;
3825 if (hasInjectionPermission(injectorPid, injectorUid)) {
3826 policyFlags |= POLICY_FLAG_TRUSTED;
3827 }
3828
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003829 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003830 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003831 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003832 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3833 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003834 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003835 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003836 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003837
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003838 int32_t flags = incomingKey.getFlags();
3839 int32_t keyCode = incomingKey.getKeyCode();
3840 int32_t metaState = incomingKey.getMetaState();
3841 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003842 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003843 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003844 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003845 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3846 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3847 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003849 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3850 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003851 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003852
3853 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3854 android::base::Timer t;
3855 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3856 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3857 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3858 std::to_string(t.duration().count()).c_str());
3859 }
3860 }
3861
3862 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003863 std::unique_ptr<KeyEntry> injectedEntry =
3864 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3865 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3866 incomingKey.getDisplayId(), policyFlags, action,
3867 flags, keyCode, incomingKey.getScanCode(), metaState,
3868 incomingKey.getRepeatCount(),
3869 incomingKey.getDownTime());
3870 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003871 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003872 }
3873
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003874 case AINPUT_EVENT_TYPE_MOTION: {
3875 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3876 int32_t action = motionEvent->getAction();
3877 size_t pointerCount = motionEvent->getPointerCount();
3878 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3879 int32_t actionButton = motionEvent->getActionButton();
3880 int32_t displayId = motionEvent->getDisplayId();
3881 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003882 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003883 }
3884
3885 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3886 nsecs_t eventTime = motionEvent->getEventTime();
3887 android::base::Timer t;
3888 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3889 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3890 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3891 std::to_string(t.duration().count()).c_str());
3892 }
3893 }
3894
3895 mLock.lock();
3896 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3897 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003898 std::unique_ptr<MotionEntry> injectedEntry =
3899 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3900 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3901 motionEvent->getDisplayId(), policyFlags, action,
3902 actionButton, motionEvent->getFlags(),
3903 motionEvent->getMetaState(),
3904 motionEvent->getButtonState(),
3905 motionEvent->getClassification(),
3906 motionEvent->getEdgeFlags(),
3907 motionEvent->getXPrecision(),
3908 motionEvent->getYPrecision(),
3909 motionEvent->getRawXCursorPosition(),
3910 motionEvent->getRawYCursorPosition(),
3911 motionEvent->getDownTime(),
3912 uint32_t(pointerCount), pointerProperties,
3913 samplePointerCoords, motionEvent->getXOffset(),
3914 motionEvent->getYOffset());
3915 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003916 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3917 sampleEventTimes += 1;
3918 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003919 std::unique_ptr<MotionEntry> nextInjectedEntry =
3920 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3921 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3922 motionEvent->getDisplayId(), policyFlags,
3923 action, actionButton, motionEvent->getFlags(),
3924 motionEvent->getMetaState(),
3925 motionEvent->getButtonState(),
3926 motionEvent->getClassification(),
3927 motionEvent->getEdgeFlags(),
3928 motionEvent->getXPrecision(),
3929 motionEvent->getYPrecision(),
3930 motionEvent->getRawXCursorPosition(),
3931 motionEvent->getRawYCursorPosition(),
3932 motionEvent->getDownTime(),
3933 uint32_t(pointerCount), pointerProperties,
3934 samplePointerCoords,
3935 motionEvent->getXOffset(),
3936 motionEvent->getYOffset());
3937 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003938 }
3939 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003940 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003941
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003942 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003943 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003944 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003945 }
3946
3947 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003948 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003949 injectionState->injectionIsAsync = true;
3950 }
3951
3952 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003953 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003954
3955 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003956 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003957 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003958 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003959 }
3960
3961 mLock.unlock();
3962
3963 if (needWake) {
3964 mLooper->wake();
3965 }
3966
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003967 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003968 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003969 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003970
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003971 if (syncMode == InputEventInjectionSync::NONE) {
3972 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003973 } else {
3974 for (;;) {
3975 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003976 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003977 break;
3978 }
3979
3980 nsecs_t remainingTimeout = endTime - now();
3981 if (remainingTimeout <= 0) {
3982#if DEBUG_INJECTION
3983 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003984 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003985#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003986 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003987 break;
3988 }
3989
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003990 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003991 }
3992
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003993 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3994 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003995 while (injectionState->pendingForegroundDispatches != 0) {
3996#if DEBUG_INJECTION
3997 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003998 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003999#endif
4000 nsecs_t remainingTimeout = endTime - now();
4001 if (remainingTimeout <= 0) {
4002#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004003 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4004 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004005#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004006 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004007 break;
4008 }
4009
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004010 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004011 }
4012 }
4013 }
4014
4015 injectionState->release();
4016 } // release lock
4017
4018#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004019 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004020 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004021#endif
4022
4023 return injectionResult;
4024}
4025
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004026std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004027 std::array<uint8_t, 32> calculatedHmac;
4028 std::unique_ptr<VerifiedInputEvent> result;
4029 switch (event.getType()) {
4030 case AINPUT_EVENT_TYPE_KEY: {
4031 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4032 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4033 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004034 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004035 break;
4036 }
4037 case AINPUT_EVENT_TYPE_MOTION: {
4038 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4039 VerifiedMotionEvent verifiedMotionEvent =
4040 verifiedMotionEventFromMotionEvent(motionEvent);
4041 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004042 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004043 break;
4044 }
4045 default: {
4046 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4047 return nullptr;
4048 }
4049 }
4050 if (calculatedHmac == INVALID_HMAC) {
4051 return nullptr;
4052 }
4053 if (calculatedHmac != event.getHmac()) {
4054 return nullptr;
4055 }
4056 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004057}
4058
Michael Wrightd02c5b62014-02-10 15:10:22 -08004059bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004060 return injectorUid == 0 ||
4061 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004062}
4063
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004064void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004065 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004066 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004067 if (injectionState) {
4068#if DEBUG_INJECTION
4069 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004070 "injectorPid=%d, injectorUid=%d",
4071 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004072#endif
4073
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004074 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004075 // Log the outcome since the injector did not wait for the injection result.
4076 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004077 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004078 ALOGV("Asynchronous input event injection succeeded.");
4079 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004080 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004081 ALOGW("Asynchronous input event injection failed.");
4082 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004083 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004084 ALOGW("Asynchronous input event injection permission denied.");
4085 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004086 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004087 ALOGW("Asynchronous input event injection timed out.");
4088 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004089 case InputEventInjectionResult::PENDING:
4090 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4091 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004092 }
4093 }
4094
4095 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004096 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004097 }
4098}
4099
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004100void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4101 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004102 if (injectionState) {
4103 injectionState->pendingForegroundDispatches += 1;
4104 }
4105}
4106
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004107void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4108 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004109 if (injectionState) {
4110 injectionState->pendingForegroundDispatches -= 1;
4111
4112 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004113 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004114 }
4115 }
4116}
4117
Vishnu Nairad321cd2020-08-20 16:40:21 -07004118const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004119 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004120 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
4121 auto it = mWindowHandlesByDisplay.find(displayId);
4122 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004123}
4124
Michael Wrightd02c5b62014-02-10 15:10:22 -08004125sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004126 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004127 if (windowHandleToken == nullptr) {
4128 return nullptr;
4129 }
4130
Arthur Hungb92218b2018-08-14 12:00:21 +08004131 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004132 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004133 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004134 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004135 return windowHandle;
4136 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004137 }
4138 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004139 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004140}
4141
Vishnu Nairad321cd2020-08-20 16:40:21 -07004142sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4143 int displayId) const {
4144 if (windowHandleToken == nullptr) {
4145 return nullptr;
4146 }
4147
4148 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
4149 if (windowHandle->getToken() == windowHandleToken) {
4150 return windowHandle;
4151 }
4152 }
4153 return nullptr;
4154}
4155
4156sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Vishnu Nairc519ff72021-01-21 08:23:08 -08004157 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004158 return getWindowHandleLocked(focusedToken, displayId);
4159}
4160
Mady Mellor017bcd12020-06-23 19:12:00 +00004161bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
4162 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004163 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00004164 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004165 if (handle->getId() == windowHandle->getId() &&
4166 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004167 if (windowHandle->getInfo()->displayId != it.first) {
4168 ALOGE("Found window %s in display %" PRId32
4169 ", but it should belong to display %" PRId32,
4170 windowHandle->getName().c_str(), it.first,
4171 windowHandle->getInfo()->displayId);
4172 }
4173 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08004174 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004175 }
4176 }
4177 return false;
4178}
4179
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004180bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
4181 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4182 const bool noInputChannel =
4183 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4184 if (connection != nullptr && noInputChannel) {
4185 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4186 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4187 return false;
4188 }
4189
4190 if (connection == nullptr) {
4191 if (!noInputChannel) {
4192 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4193 }
4194 return false;
4195 }
4196 if (!connection->responsive) {
4197 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4198 return false;
4199 }
4200 return true;
4201}
4202
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004203std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4204 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07004205 size_t count = mInputChannelsByToken.count(token);
4206 if (count == 0) {
4207 return nullptr;
4208 }
4209 return mInputChannelsByToken.at(token);
4210}
4211
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004212void InputDispatcher::updateWindowHandlesForDisplayLocked(
4213 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
4214 if (inputWindowHandles.empty()) {
4215 // Remove all handles on a display if there are no windows left.
4216 mWindowHandlesByDisplay.erase(displayId);
4217 return;
4218 }
4219
4220 // Since we compare the pointer of input window handles across window updates, we need
4221 // to make sure the handle object for the same window stays unchanged across updates.
4222 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07004223 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004224 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004225 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004226 }
4227
4228 std::vector<sp<InputWindowHandle>> newHandles;
4229 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
4230 if (!handle->updateInfo()) {
4231 // handle no longer valid
4232 continue;
4233 }
4234
4235 const InputWindowInfo* info = handle->getInfo();
4236 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4237 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4238 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01004239 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4240 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
4241 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004242 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004243 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004244 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004245 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004246 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004247 }
4248
4249 if (info->displayId != displayId) {
4250 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4251 handle->getName().c_str(), displayId, info->displayId);
4252 continue;
4253 }
4254
Robert Carredd13602020-04-13 17:24:34 -07004255 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4256 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004257 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004258 oldHandle->updateFrom(handle);
4259 newHandles.push_back(oldHandle);
4260 } else {
4261 newHandles.push_back(handle);
4262 }
4263 }
4264
4265 // Insert or replace
4266 mWindowHandlesByDisplay[displayId] = newHandles;
4267}
4268
Arthur Hung72d8dc32020-03-28 00:48:39 +00004269void InputDispatcher::setInputWindows(
4270 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4271 { // acquire lock
4272 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004273 for (const auto& [displayId, handles] : handlesPerDisplay) {
4274 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004275 }
4276 }
4277 // Wake up poll loop since it may need to make new input dispatching choices.
4278 mLooper->wake();
4279}
4280
Arthur Hungb92218b2018-08-14 12:00:21 +08004281/**
4282 * Called from InputManagerService, update window handle list by displayId that can receive input.
4283 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4284 * If set an empty list, remove all handles from the specific display.
4285 * For focused handle, check if need to change and send a cancel event to previous one.
4286 * For removed handle, check if need to send a cancel event if already in touch.
4287 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004288void InputDispatcher::setInputWindowsLocked(
4289 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004290 if (DEBUG_FOCUS) {
4291 std::string windowList;
4292 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4293 windowList += iwh->getName() + " ";
4294 }
4295 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4296 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004297
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004298 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4299 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4300 const bool noInputWindow =
4301 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4302 if (noInputWindow && window->getToken() != nullptr) {
4303 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4304 window->getName().c_str());
4305 window->releaseChannel();
4306 }
4307 }
4308
Arthur Hung72d8dc32020-03-28 00:48:39 +00004309 // Copy old handles for release if they are no longer present.
4310 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004311
Arthur Hung72d8dc32020-03-28 00:48:39 +00004312 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004313
Vishnu Nair958da932020-08-21 17:12:37 -07004314 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4315 if (mLastHoverWindowHandle &&
4316 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4317 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004318 mLastHoverWindowHandle = nullptr;
4319 }
4320
Vishnu Nairc519ff72021-01-21 08:23:08 -08004321 std::optional<FocusResolver::FocusChanges> changes =
4322 mFocusResolver.setInputWindows(displayId, windowHandles);
4323 if (changes) {
4324 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004325 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004326
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004327 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4328 mTouchStatesByDisplay.find(displayId);
4329 if (stateIt != mTouchStatesByDisplay.end()) {
4330 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004331 for (size_t i = 0; i < state.windows.size();) {
4332 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004333 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004334 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004335 ALOGD("Touched window was removed: %s in display %" PRId32,
4336 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004337 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004338 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004339 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4340 if (touchedInputChannel != nullptr) {
4341 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4342 "touched window was removed");
4343 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004344 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004345 state.windows.erase(state.windows.begin() + i);
4346 } else {
4347 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004348 }
4349 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004350 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004351
Arthur Hung72d8dc32020-03-28 00:48:39 +00004352 // Release information for windows that are no longer present.
4353 // This ensures that unused input channels are released promptly.
4354 // Otherwise, they might stick around until the window handle is destroyed
4355 // which might not happen until the next GC.
4356 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004357 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004358 if (DEBUG_FOCUS) {
4359 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004360 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004361 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004362 // To avoid making too many calls into the compat framework, only
4363 // check for window flags when windows are going away.
4364 // TODO(b/157929241) : delete this. This is only needed temporarily
4365 // in order to gather some data about the flag usage
4366 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4367 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4368 oldWindowHandle->getName().c_str());
4369 if (mCompatService != nullptr) {
4370 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4371 oldWindowHandle->getInfo()->ownerUid);
4372 }
4373 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004374 }
chaviw291d88a2019-02-14 10:33:58 -08004375 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004376}
4377
4378void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004379 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004380 if (DEBUG_FOCUS) {
4381 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4382 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4383 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004384 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004385 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004386
Chris Yea209fde2020-07-22 13:54:51 -07004387 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004388 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004389
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004390 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4391 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004392 }
4393
Chris Yea209fde2020-07-22 13:54:51 -07004394 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004395 if (inputApplicationHandle != nullptr) {
4396 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4397 } else {
4398 mFocusedApplicationHandlesByDisplay.erase(displayId);
4399 }
4400
4401 // No matter what the old focused application was, stop waiting on it because it is
4402 // no longer focused.
4403 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004404 } // release lock
4405
4406 // Wake up poll loop since it may need to make new input dispatching choices.
4407 mLooper->wake();
4408}
4409
Tiger Huang721e26f2018-07-24 22:26:19 +08004410/**
4411 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4412 * the display not specified.
4413 *
4414 * We track any unreleased events for each window. If a window loses the ability to receive the
4415 * released event, we will send a cancel event to it. So when the focused display is changed, we
4416 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4417 * display. The display-specified events won't be affected.
4418 */
4419void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004420 if (DEBUG_FOCUS) {
4421 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4422 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004423 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004424 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004425
4426 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004427 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004428 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004429 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004430 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004431 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004432 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004433 CancelationOptions
4434 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4435 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004436 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004437 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4438 }
4439 }
4440 mFocusedDisplayId = displayId;
4441
Chris Ye3c2d6f52020-08-09 10:39:48 -07004442 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004443 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004444 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004445
Vishnu Nairad321cd2020-08-20 16:40:21 -07004446 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004447 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004448 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004449 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004450 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004451 }
4452 }
4453 }
4454
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004455 if (DEBUG_FOCUS) {
4456 logDispatchStateLocked();
4457 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004458 } // release lock
4459
4460 // Wake up poll loop since it may need to make new input dispatching choices.
4461 mLooper->wake();
4462}
4463
Michael Wrightd02c5b62014-02-10 15:10:22 -08004464void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004465 if (DEBUG_FOCUS) {
4466 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4467 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004468
4469 bool changed;
4470 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004471 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004472
4473 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4474 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004475 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004476 }
4477
4478 if (mDispatchEnabled && !enabled) {
4479 resetAndDropEverythingLocked("dispatcher is being disabled");
4480 }
4481
4482 mDispatchEnabled = enabled;
4483 mDispatchFrozen = frozen;
4484 changed = true;
4485 } else {
4486 changed = false;
4487 }
4488
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004489 if (DEBUG_FOCUS) {
4490 logDispatchStateLocked();
4491 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004492 } // release lock
4493
4494 if (changed) {
4495 // Wake up poll loop since it may need to make new input dispatching choices.
4496 mLooper->wake();
4497 }
4498}
4499
4500void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004501 if (DEBUG_FOCUS) {
4502 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4503 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004504
4505 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004506 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004507
4508 if (mInputFilterEnabled == enabled) {
4509 return;
4510 }
4511
4512 mInputFilterEnabled = enabled;
4513 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4514 } // release lock
4515
4516 // Wake up poll loop since there might be work to do to drop everything.
4517 mLooper->wake();
4518}
4519
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004520void InputDispatcher::setInTouchMode(bool inTouchMode) {
4521 std::scoped_lock lock(mLock);
4522 mInTouchMode = inTouchMode;
4523}
4524
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004525void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4526 if (opacity < 0 || opacity > 1) {
4527 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4528 return;
4529 }
4530
4531 std::scoped_lock lock(mLock);
4532 mMaximumObscuringOpacityForTouch = opacity;
4533}
4534
4535void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4536 std::scoped_lock lock(mLock);
4537 mBlockUntrustedTouchesMode = mode;
4538}
4539
chaviwfbe5d9c2018-12-26 12:23:37 -08004540bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4541 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004542 if (DEBUG_FOCUS) {
4543 ALOGD("Trivial transfer to same window.");
4544 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004545 return true;
4546 }
4547
Michael Wrightd02c5b62014-02-10 15:10:22 -08004548 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004549 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004550
chaviwfbe5d9c2018-12-26 12:23:37 -08004551 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4552 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004553 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004554 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004555 return false;
4556 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004557 if (DEBUG_FOCUS) {
4558 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4559 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4560 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004561 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004562 if (DEBUG_FOCUS) {
4563 ALOGD("Cannot transfer focus because windows are on different displays.");
4564 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004565 return false;
4566 }
4567
4568 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004569 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4570 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004571 for (size_t i = 0; i < state.windows.size(); i++) {
4572 const TouchedWindow& touchedWindow = state.windows[i];
4573 if (touchedWindow.windowHandle == fromWindowHandle) {
4574 int32_t oldTargetFlags = touchedWindow.targetFlags;
4575 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004576
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004577 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004578
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004579 int32_t newTargetFlags = oldTargetFlags &
4580 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4581 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004582 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004583
Jeff Brownf086ddb2014-02-11 14:28:48 -08004584 found = true;
4585 goto Found;
4586 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004587 }
4588 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004589 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004590
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004591 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004592 if (DEBUG_FOCUS) {
4593 ALOGD("Focus transfer failed because from window did not have focus.");
4594 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004595 return false;
4596 }
4597
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004598 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4599 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004600 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004601 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004602 CancelationOptions
4603 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4604 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004605 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004606 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004607 }
4608
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004609 if (DEBUG_FOCUS) {
4610 logDispatchStateLocked();
4611 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004612 } // release lock
4613
4614 // Wake up poll loop since it may need to make new input dispatching choices.
4615 mLooper->wake();
4616 return true;
4617}
4618
4619void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004620 if (DEBUG_FOCUS) {
4621 ALOGD("Resetting and dropping all events (%s).", reason);
4622 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004623
4624 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4625 synthesizeCancelationEventsForAllConnectionsLocked(options);
4626
4627 resetKeyRepeatLocked();
4628 releasePendingEventLocked();
4629 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004630 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004631
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004632 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004633 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004634 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004635 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004636}
4637
4638void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004639 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004640 dumpDispatchStateLocked(dump);
4641
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004642 std::istringstream stream(dump);
4643 std::string line;
4644
4645 while (std::getline(stream, line, '\n')) {
4646 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004647 }
4648}
4649
Prabir Pradhan99987712020-11-10 18:43:05 -08004650std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4651 std::string dump;
4652
4653 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4654 toString(mFocusedWindowRequestedPointerCapture));
4655
4656 std::string windowName = "None";
4657 if (mWindowTokenWithPointerCapture) {
4658 const sp<InputWindowHandle> captureWindowHandle =
4659 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4660 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4661 : "token has capture without window";
4662 }
4663 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4664
4665 return dump;
4666}
4667
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004668void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004669 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4670 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4671 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004672 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004673
Tiger Huang721e26f2018-07-24 22:26:19 +08004674 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4675 dump += StringPrintf(INDENT "FocusedApplications:\n");
4676 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4677 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004678 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004679 const std::chrono::duration timeout =
4680 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004681 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004682 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004683 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004684 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004685 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004686 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004687 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004688
Vishnu Nairc519ff72021-01-21 08:23:08 -08004689 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08004690 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004691
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004692 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004693 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004694 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4695 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004696 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004697 state.displayId, toString(state.down), toString(state.split),
4698 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004699 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004700 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004701 for (size_t i = 0; i < state.windows.size(); i++) {
4702 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004703 dump += StringPrintf(INDENT4
4704 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4705 i, touchedWindow.windowHandle->getName().c_str(),
4706 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004707 }
4708 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004709 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004710 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004711 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004712 dump += INDENT3 "Portal windows:\n";
4713 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004714 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004715 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4716 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004717 }
4718 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004719 }
4720 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004721 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004722 }
4723
Arthur Hungb92218b2018-08-14 12:00:21 +08004724 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004725 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004726 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004727 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004728 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004729 dump += INDENT2 "Windows:\n";
4730 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004731 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004732 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004733
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004734 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004735 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004736 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004737 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004738 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00004739 "applicationInfo.name=%s, "
4740 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004741 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004742 i, windowInfo->name.c_str(), windowInfo->id,
4743 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004744 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004745 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004746 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004747 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004748 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004749 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004750 windowInfo->frameLeft, windowInfo->frameTop,
4751 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004752 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00004753 windowInfo->applicationInfo.name.c_str(),
4754 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004755 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004756 dump += StringPrintf(", inputFeatures=%s",
4757 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004758 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004759 "ms, trustedOverlay=%s, hasToken=%s, "
4760 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004761 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004762 millis(windowInfo->dispatchingTimeout),
4763 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004764 toString(windowInfo->token != nullptr),
4765 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004766 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004767 }
4768 } else {
4769 dump += INDENT2 "Windows: <none>\n";
4770 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004771 }
4772 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004773 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004774 }
4775
Michael Wright3dd60e22019-03-27 22:06:44 +00004776 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004777 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004778 const std::vector<Monitor>& monitors = it.second;
4779 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4780 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004781 }
4782 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004783 const std::vector<Monitor>& monitors = it.second;
4784 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4785 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004786 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004787 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004788 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004789 }
4790
4791 nsecs_t currentTime = now();
4792
4793 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004794 if (!mRecentQueue.empty()) {
4795 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004796 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004797 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004798 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004799 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004800 }
4801 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004802 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004803 }
4804
4805 // Dump event currently being dispatched.
4806 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004807 dump += INDENT "PendingEvent:\n";
4808 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004809 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004810 dump += StringPrintf(", age=%" PRId64 "ms\n",
4811 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004812 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004813 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004814 }
4815
4816 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004817 if (!mInboundQueue.empty()) {
4818 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004819 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004820 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004821 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004822 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004823 }
4824 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004825 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004826 }
4827
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004828 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004829 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004830 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4831 const KeyReplacement& replacement = pair.first;
4832 int32_t newKeyCode = pair.second;
4833 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004834 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004835 }
4836 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004837 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004838 }
4839
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004840 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004841 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004842 for (const auto& pair : mConnectionsByFd) {
4843 const sp<Connection>& connection = pair.second;
4844 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004845 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004846 pair.first, connection->getInputChannelName().c_str(),
4847 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004848 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004849
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004850 if (!connection->outboundQueue.empty()) {
4851 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4852 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004853 dump += dumpQueue(connection->outboundQueue, currentTime);
4854
Michael Wrightd02c5b62014-02-10 15:10:22 -08004855 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004856 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004857 }
4858
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004859 if (!connection->waitQueue.empty()) {
4860 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4861 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004862 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004863 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004864 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004865 }
4866 }
4867 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004868 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004869 }
4870
4871 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004872 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4873 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004874 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004875 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004876 }
4877
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004878 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004879 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4880 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4881 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004882}
4883
Michael Wright3dd60e22019-03-27 22:06:44 +00004884void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4885 const size_t numMonitors = monitors.size();
4886 for (size_t i = 0; i < numMonitors; i++) {
4887 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004888 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004889 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4890 dump += "\n";
4891 }
4892}
4893
Garfield Tan15601662020-09-22 15:32:38 -07004894base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4895 const std::string& name) {
4896#if DEBUG_CHANNEL_CREATION
4897 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004898#endif
4899
Garfield Tan15601662020-09-22 15:32:38 -07004900 std::shared_ptr<InputChannel> serverChannel;
4901 std::unique_ptr<InputChannel> clientChannel;
4902 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4903
4904 if (result) {
4905 return base::Error(result) << "Failed to open input channel pair with name " << name;
4906 }
4907
Michael Wrightd02c5b62014-02-10 15:10:22 -08004908 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004909 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004910 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004911
Garfield Tan15601662020-09-22 15:32:38 -07004912 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004913 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004914 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004915
Michael Wrightd02c5b62014-02-10 15:10:22 -08004916 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4917 } // release lock
4918
4919 // Wake the looper because some connections have changed.
4920 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004921 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004922}
4923
Garfield Tan15601662020-09-22 15:32:38 -07004924base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004925 int32_t displayId, bool isGestureMonitor, const std::string& name, int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07004926 std::shared_ptr<InputChannel> serverChannel;
4927 std::unique_ptr<InputChannel> clientChannel;
4928 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4929 if (result) {
4930 return base::Error(result) << "Failed to open input channel pair with name " << name;
4931 }
4932
Michael Wright3dd60e22019-03-27 22:06:44 +00004933 { // acquire lock
4934 std::scoped_lock _l(mLock);
4935
4936 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004937 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4938 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004939 }
4940
Garfield Tan15601662020-09-22 15:32:38 -07004941 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004942
Garfield Tan15601662020-09-22 15:32:38 -07004943 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004944 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004945 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004946
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004947 auto& monitorsByDisplay =
4948 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004949 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00004950
4951 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004952 }
Garfield Tan15601662020-09-22 15:32:38 -07004953
Michael Wright3dd60e22019-03-27 22:06:44 +00004954 // Wake the looper because some connections have changed.
4955 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004956 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004957}
4958
Garfield Tan15601662020-09-22 15:32:38 -07004959status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004960 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004961 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004962
Garfield Tan15601662020-09-22 15:32:38 -07004963 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004964 if (status) {
4965 return status;
4966 }
4967 } // release lock
4968
4969 // Wake the poll loop because removing the connection may have changed the current
4970 // synchronization state.
4971 mLooper->wake();
4972 return OK;
4973}
4974
Garfield Tan15601662020-09-22 15:32:38 -07004975status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
4976 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004977 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004978 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00004979 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08004980 return BAD_VALUE;
4981 }
4982
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004983 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004984 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07004985
Michael Wrightd02c5b62014-02-10 15:10:22 -08004986 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004987 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004988 }
4989
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004990 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004991
4992 nsecs_t currentTime = now();
4993 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4994
4995 connection->status = Connection::STATUS_ZOMBIE;
4996 return OK;
4997}
4998
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004999void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5000 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5001 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005002}
5003
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005004void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005005 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005006 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005007 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005008 std::vector<Monitor>& monitors = it->second;
5009 const size_t numMonitors = monitors.size();
5010 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005011 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005012 monitors.erase(monitors.begin() + i);
5013 break;
5014 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005015 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005016 if (monitors.empty()) {
5017 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005018 } else {
5019 ++it;
5020 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005021 }
5022}
5023
Michael Wright3dd60e22019-03-27 22:06:44 +00005024status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5025 { // acquire lock
5026 std::scoped_lock _l(mLock);
5027 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5028
5029 if (!foundDisplayId) {
5030 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5031 return BAD_VALUE;
5032 }
5033 int32_t displayId = foundDisplayId.value();
5034
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005035 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5036 mTouchStatesByDisplay.find(displayId);
5037 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005038 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5039 return BAD_VALUE;
5040 }
5041
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005042 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005043 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005044 std::optional<int32_t> foundDeviceId;
5045 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005046 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005047 requestingChannel = touchedMonitor.monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005048 foundDeviceId = state.deviceId;
5049 }
5050 }
5051 if (!foundDeviceId || !state.down) {
5052 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005053 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005054 return BAD_VALUE;
5055 }
5056 int32_t deviceId = foundDeviceId.value();
5057
5058 // Send cancel events to all the input channels we're stealing from.
5059 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005060 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005061 options.deviceId = deviceId;
5062 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005063 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005064 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005065 std::shared_ptr<InputChannel> channel =
5066 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005067 if (channel != nullptr) {
5068 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005069 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005070 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005071 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005072 canceledWindows += "]";
5073 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5074 canceledWindows.c_str());
5075
Michael Wright3dd60e22019-03-27 22:06:44 +00005076 // Then clear the current touch state so we stop dispatching to them as well.
5077 state.filterNonMonitors();
5078 }
5079 return OK;
5080}
5081
Prabir Pradhan99987712020-11-10 18:43:05 -08005082void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5083 { // acquire lock
5084 std::scoped_lock _l(mLock);
5085 if (DEBUG_FOCUS) {
5086 const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
5087 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5088 windowHandle != nullptr ? windowHandle->getName().c_str()
5089 : "token without window");
5090 }
5091
Vishnu Nairc519ff72021-01-21 08:23:08 -08005092 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005093 if (focusedToken != windowToken) {
5094 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5095 enabled ? "enable" : "disable");
5096 return;
5097 }
5098
5099 if (enabled == mFocusedWindowRequestedPointerCapture) {
5100 ALOGW("Ignoring request to %s Pointer Capture: "
5101 "window has %s requested pointer capture.",
5102 enabled ? "enable" : "disable", enabled ? "already" : "not");
5103 return;
5104 }
5105
5106 mFocusedWindowRequestedPointerCapture = enabled;
5107 setPointerCaptureLocked(enabled);
5108 } // release lock
5109
5110 // Wake the thread to process command entries.
5111 mLooper->wake();
5112}
5113
Michael Wright3dd60e22019-03-27 22:06:44 +00005114std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5115 const sp<IBinder>& token) {
5116 for (const auto& it : mGestureMonitorsByDisplay) {
5117 const std::vector<Monitor>& monitors = it.second;
5118 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005119 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005120 return it.first;
5121 }
5122 }
5123 }
5124 return std::nullopt;
5125}
5126
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005127std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5128 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5129 if (gesturePid.has_value()) {
5130 return gesturePid;
5131 }
5132 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5133}
5134
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005135sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005136 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005137 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005138 }
5139
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005140 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005141 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005142 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005143 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005144 }
5145 }
Robert Carr4e670e52018-08-15 13:26:12 -07005146
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005147 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005148}
5149
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005150std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5151 sp<Connection> connection = getConnectionLocked(connectionToken);
5152 if (connection == nullptr) {
5153 return "<nullptr>";
5154 }
5155 return connection->getInputChannelName();
5156}
5157
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005158void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005159 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005160 removeByValue(mConnectionsByFd, connection);
5161}
5162
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005163void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5164 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10005165 bool handled, nsecs_t consumeTime) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005166 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5167 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005168 commandEntry->connection = connection;
5169 commandEntry->eventTime = currentTime;
5170 commandEntry->seq = seq;
5171 commandEntry->handled = handled;
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10005172 commandEntry->consumeTime = consumeTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005173 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005174}
5175
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005176void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5177 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005178 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005179 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005180
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005181 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5182 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005183 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005184 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005185}
5186
Vishnu Nairad321cd2020-08-20 16:40:21 -07005187void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5188 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005189 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5190 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005191 commandEntry->oldToken = oldToken;
5192 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005193 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005194}
5195
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005196void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5197 if (connection == nullptr) {
5198 LOG_ALWAYS_FATAL("Caller must check for nullness");
5199 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005200 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5201 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005202 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005203 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005204 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005205 return;
5206 }
5207 /**
5208 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5209 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5210 * has changed. This could cause newer entries to time out before the already dispatched
5211 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5212 * processes the events linearly. So providing information about the oldest entry seems to be
5213 * most useful.
5214 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005215 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005216 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5217 std::string reason =
5218 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005219 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005220 ns2ms(currentWait),
5221 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005222 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005223 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005224
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005225 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5226
5227 // Stop waking up for events on this connection, it is already unresponsive
5228 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005229}
5230
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005231void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5232 std::string reason =
5233 StringPrintf("%s does not have a focused window", application->getName().c_str());
5234 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005235
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005236 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5237 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5238 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005239 postCommandLocked(std::move(commandEntry));
5240}
5241
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005242void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5243 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5244 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5245 commandEntry->obscuringPackage = obscuringPackage;
5246 postCommandLocked(std::move(commandEntry));
5247}
5248
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005249void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
5250 const std::string& reason) {
5251 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5252 updateLastAnrStateLocked(windowLabel, reason);
5253}
5254
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005255void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5256 const std::string& reason) {
5257 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005258 updateLastAnrStateLocked(windowLabel, reason);
5259}
5260
5261void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5262 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005263 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005264 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005265 struct tm tm;
5266 localtime_r(&t, &tm);
5267 char timestr[64];
5268 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005269 mLastAnrState.clear();
5270 mLastAnrState += INDENT "ANR:\n";
5271 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005272 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5273 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005274 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005275}
5276
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005277void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005278 mLock.unlock();
5279
5280 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5281
5282 mLock.lock();
5283}
5284
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005285void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005286 sp<Connection> connection = commandEntry->connection;
5287
5288 if (connection->status != Connection::STATUS_ZOMBIE) {
5289 mLock.unlock();
5290
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005291 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005292
5293 mLock.lock();
5294 }
5295}
5296
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005297void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005298 sp<IBinder> oldToken = commandEntry->oldToken;
5299 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005300 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005301 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005302 mLock.lock();
5303}
5304
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005305void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005306 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005307
5308 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5309
5310 mLock.lock();
5311}
5312
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005313void InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005314 mLock.unlock();
5315
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005316 mPolicy->notifyWindowUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005317
5318 mLock.lock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005319}
5320
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005321void InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005322 mLock.unlock();
5323
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005324 mPolicy->notifyMonitorUnresponsive(commandEntry->pid, commandEntry->reason);
5325
5326 mLock.lock();
5327}
5328
5329void InputDispatcher::doNotifyWindowResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5330 mLock.unlock();
5331
5332 mPolicy->notifyWindowResponsive(commandEntry->connectionToken);
5333
5334 mLock.lock();
5335}
5336
5337void InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5338 mLock.unlock();
5339
5340 mPolicy->notifyMonitorResponsive(commandEntry->pid);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005341
5342 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005343}
5344
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005345void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5346 mLock.unlock();
5347
5348 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5349
5350 mLock.lock();
5351}
5352
Michael Wrightd02c5b62014-02-10 15:10:22 -08005353void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5354 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005355 KeyEntry& entry = *(commandEntry->keyEntry);
5356 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005357
5358 mLock.unlock();
5359
Michael Wright2b3c3302018-03-02 17:19:13 +00005360 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005361 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005362 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005363 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5364 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005365 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005366 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005367
5368 mLock.lock();
5369
5370 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005371 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005372 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005373 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005374 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005375 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5376 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005377 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005378}
5379
chaviwfd6d3512019-03-25 13:23:49 -07005380void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5381 mLock.unlock();
5382 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5383 mLock.lock();
5384}
5385
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005386/**
5387 * Connection is responsive if it has no events in the waitQueue that are older than the
5388 * current time.
5389 */
5390static bool isConnectionResponsive(const Connection& connection) {
5391 const nsecs_t currentTime = now();
5392 for (const DispatchEntry* entry : connection.waitQueue) {
5393 if (entry->timeoutTime < currentTime) {
5394 return false;
5395 }
5396 }
5397 return true;
5398}
5399
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005400void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005401 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005402 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005403 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005404 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005405
5406 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005407 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005408 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005409 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005410 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005411 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005412 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005413 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005414 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5415 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005416 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005417 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005418
5419 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005420 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005421 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005422 restartEvent =
5423 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005424 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005425 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005426 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5427 handled);
5428 } else {
5429 restartEvent = false;
5430 }
5431
5432 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005433 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005434 // contents of the wait queue to have been drained, so we need to double-check
5435 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005436 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5437 if (dispatchEntryIt != connection->waitQueue.end()) {
5438 dispatchEntry = *dispatchEntryIt;
5439 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005440 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5441 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005442 if (!connection->responsive) {
5443 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005444 if (connection->responsive) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005445 // The connection was unresponsive, and now it's responsive.
5446 processConnectionResponsiveLocked(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005447 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005448 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005449 traceWaitQueueLength(connection);
5450 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005451 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005452 traceOutboundQueueLength(connection);
5453 } else {
5454 releaseDispatchEntry(dispatchEntry);
5455 }
5456 }
5457
5458 // Start the next dispatch cycle for this connection.
5459 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005460}
5461
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005462void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
5463 std::unique_ptr<CommandEntry> monitorUnresponsiveCommand = std::make_unique<CommandEntry>(
5464 &InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible);
5465 monitorUnresponsiveCommand->pid = pid;
5466 monitorUnresponsiveCommand->reason = std::move(reason);
5467 postCommandLocked(std::move(monitorUnresponsiveCommand));
5468}
5469
5470void InputDispatcher::sendWindowUnresponsiveCommandLocked(sp<IBinder> connectionToken,
5471 std::string reason) {
5472 std::unique_ptr<CommandEntry> windowUnresponsiveCommand = std::make_unique<CommandEntry>(
5473 &InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible);
5474 windowUnresponsiveCommand->connectionToken = std::move(connectionToken);
5475 windowUnresponsiveCommand->reason = std::move(reason);
5476 postCommandLocked(std::move(windowUnresponsiveCommand));
5477}
5478
5479void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
5480 std::unique_ptr<CommandEntry> monitorResponsiveCommand = std::make_unique<CommandEntry>(
5481 &InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible);
5482 monitorResponsiveCommand->pid = pid;
5483 postCommandLocked(std::move(monitorResponsiveCommand));
5484}
5485
5486void InputDispatcher::sendWindowResponsiveCommandLocked(sp<IBinder> connectionToken) {
5487 std::unique_ptr<CommandEntry> windowResponsiveCommand = std::make_unique<CommandEntry>(
5488 &InputDispatcher::doNotifyWindowResponsiveLockedInterruptible);
5489 windowResponsiveCommand->connectionToken = std::move(connectionToken);
5490 postCommandLocked(std::move(windowResponsiveCommand));
5491}
5492
5493/**
5494 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5495 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5496 * command entry to the command queue.
5497 */
5498void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5499 std::string reason) {
5500 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5501 if (connection.monitor) {
5502 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5503 reason.c_str());
5504 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5505 if (!pid.has_value()) {
5506 ALOGE("Could not find unresponsive monitor for connection %s",
5507 connection.inputChannel->getName().c_str());
5508 return;
5509 }
5510 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5511 return;
5512 }
5513 // If not a monitor, must be a window
5514 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5515 reason.c_str());
5516 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5517}
5518
5519/**
5520 * Tell the policy that a connection has become responsive so that it can stop ANR.
5521 */
5522void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5523 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5524 if (connection.monitor) {
5525 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5526 if (!pid.has_value()) {
5527 ALOGE("Could not find responsive monitor for connection %s",
5528 connection.inputChannel->getName().c_str());
5529 return;
5530 }
5531 sendMonitorResponsiveCommandLocked(pid.value());
5532 return;
5533 }
5534 // If not a monitor, must be a window
5535 sendWindowResponsiveCommandLocked(connectionToken);
5536}
5537
Michael Wrightd02c5b62014-02-10 15:10:22 -08005538bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005539 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005540 KeyEntry& keyEntry, bool handled) {
5541 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005542 if (!handled) {
5543 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005544 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005545 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005546 return false;
5547 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005548
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005549 // Get the fallback key state.
5550 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005551 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005552 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005553 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005554 connection->inputState.removeFallbackKey(originalKeyCode);
5555 }
5556
5557 if (handled || !dispatchEntry->hasForegroundTarget()) {
5558 // If the application handles the original key for which we previously
5559 // generated a fallback or if the window is not a foreground window,
5560 // then cancel the associated fallback key, if any.
5561 if (fallbackKeyCode != -1) {
5562 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005563#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005564 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005565 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005566 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005567#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005568 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005569 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005570
5571 mLock.unlock();
5572
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005573 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005574 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005575
5576 mLock.lock();
5577
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005578 // Cancel the fallback key.
5579 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005580 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005581 "application handled the original non-fallback key "
5582 "or is no longer a foreground target, "
5583 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005584 options.keyCode = fallbackKeyCode;
5585 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005586 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005587 connection->inputState.removeFallbackKey(originalKeyCode);
5588 }
5589 } else {
5590 // If the application did not handle a non-fallback key, first check
5591 // that we are in a good state to perform unhandled key event processing
5592 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005593 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005594 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005595#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005596 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005597 "since this is not an initial down. "
5598 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005599 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005600#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005601 return false;
5602 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005603
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005604 // Dispatch the unhandled key to the policy.
5605#if DEBUG_OUTBOUND_EVENT_DETAILS
5606 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005607 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005608 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005609#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005610 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005611
5612 mLock.unlock();
5613
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005614 bool fallback =
5615 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005616 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005617
5618 mLock.lock();
5619
5620 if (connection->status != Connection::STATUS_NORMAL) {
5621 connection->inputState.removeFallbackKey(originalKeyCode);
5622 return false;
5623 }
5624
5625 // Latch the fallback keycode for this key on an initial down.
5626 // The fallback keycode cannot change at any other point in the lifecycle.
5627 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005628 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005629 fallbackKeyCode = event.getKeyCode();
5630 } else {
5631 fallbackKeyCode = AKEYCODE_UNKNOWN;
5632 }
5633 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5634 }
5635
5636 ALOG_ASSERT(fallbackKeyCode != -1);
5637
5638 // Cancel the fallback key if the policy decides not to send it anymore.
5639 // We will continue to dispatch the key to the policy but we will no
5640 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005641 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5642 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005643#if DEBUG_OUTBOUND_EVENT_DETAILS
5644 if (fallback) {
5645 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005646 "as a fallback for %d, but on the DOWN it had requested "
5647 "to send %d instead. Fallback canceled.",
5648 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005649 } else {
5650 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005651 "but on the DOWN it had requested to send %d. "
5652 "Fallback canceled.",
5653 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005654 }
5655#endif
5656
5657 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5658 "canceling fallback, policy no longer desires it");
5659 options.keyCode = fallbackKeyCode;
5660 synthesizeCancelationEventsForConnectionLocked(connection, options);
5661
5662 fallback = false;
5663 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005664 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005665 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005666 }
5667 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005668
5669#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005670 {
5671 std::string msg;
5672 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5673 connection->inputState.getFallbackKeys();
5674 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005675 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005676 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005677 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005678 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005679 }
5680#endif
5681
5682 if (fallback) {
5683 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005684 keyEntry.eventTime = event.getEventTime();
5685 keyEntry.deviceId = event.getDeviceId();
5686 keyEntry.source = event.getSource();
5687 keyEntry.displayId = event.getDisplayId();
5688 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5689 keyEntry.keyCode = fallbackKeyCode;
5690 keyEntry.scanCode = event.getScanCode();
5691 keyEntry.metaState = event.getMetaState();
5692 keyEntry.repeatCount = event.getRepeatCount();
5693 keyEntry.downTime = event.getDownTime();
5694 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005695
5696#if DEBUG_OUTBOUND_EVENT_DETAILS
5697 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005698 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005699 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005700#endif
5701 return true; // restart the event
5702 } else {
5703#if DEBUG_OUTBOUND_EVENT_DETAILS
5704 ALOGD("Unhandled key event: No fallback key.");
5705#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005706
5707 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005708 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005709 }
5710 }
5711 return false;
5712}
5713
5714bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005715 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005716 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005717 return false;
5718}
5719
5720void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5721 mLock.unlock();
5722
Sean Stoutb4e0a592021-02-23 07:34:53 -08005723 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType,
5724 commandEntry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005725
5726 mLock.lock();
5727}
5728
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005729void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5730 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005731 // TODO Write some statistics about how long we spend waiting.
5732}
5733
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005734/**
5735 * Report the touch event latency to the statsd server.
5736 * Input events are reported for statistics if:
5737 * - This is a touchscreen event
5738 * - InputFilter is not enabled
5739 * - Event is not injected or synthesized
5740 *
5741 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5742 * from getting aggregated with the "old" data.
5743 */
5744void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5745 REQUIRES(mLock) {
5746 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5747 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5748 if (!reportForStatistics) {
5749 return;
5750 }
5751
5752 if (mTouchStatistics.shouldReport()) {
5753 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5754 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5755 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5756 mTouchStatistics.reset();
5757 }
5758 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5759 mTouchStatistics.addValue(latencyMicros);
5760}
5761
Michael Wrightd02c5b62014-02-10 15:10:22 -08005762void InputDispatcher::traceInboundQueueLengthLocked() {
5763 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005764 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005765 }
5766}
5767
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005768void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005769 if (ATRACE_ENABLED()) {
5770 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005771 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005772 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005773 }
5774}
5775
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005776void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005777 if (ATRACE_ENABLED()) {
5778 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005779 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005780 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005781 }
5782}
5783
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005784void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005785 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005786
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005787 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005788 dumpDispatchStateLocked(dump);
5789
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005790 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005791 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005792 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005793 }
5794}
5795
5796void InputDispatcher::monitor() {
5797 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005798 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005799 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005800 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005801}
5802
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005803/**
5804 * Wake up the dispatcher and wait until it processes all events and commands.
5805 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5806 * this method can be safely called from any thread, as long as you've ensured that
5807 * the work you are interested in completing has already been queued.
5808 */
5809bool InputDispatcher::waitForIdle() {
5810 /**
5811 * Timeout should represent the longest possible time that a device might spend processing
5812 * events and commands.
5813 */
5814 constexpr std::chrono::duration TIMEOUT = 100ms;
5815 std::unique_lock lock(mLock);
5816 mLooper->wake();
5817 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5818 return result == std::cv_status::no_timeout;
5819}
5820
Vishnu Naire798b472020-07-23 13:52:21 -07005821/**
5822 * Sets focus to the window identified by the token. This must be called
5823 * after updating any input window handles.
5824 *
5825 * Params:
5826 * request.token - input channel token used to identify the window that should gain focus.
5827 * request.focusedToken - the token that the caller expects currently to be focused. If the
5828 * specified token does not match the currently focused window, this request will be dropped.
5829 * If the specified focused token matches the currently focused window, the call will succeed.
5830 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5831 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5832 * when requesting the focus change. This determines which request gets
5833 * precedence if there is a focus change request from another source such as pointer down.
5834 */
Vishnu Nair958da932020-08-21 17:12:37 -07005835void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5836 { // acquire lock
5837 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005838 std::optional<FocusResolver::FocusChanges> changes =
5839 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
5840 if (changes) {
5841 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07005842 }
5843 } // release lock
5844 // Wake up poll loop since it may need to make new input dispatching choices.
5845 mLooper->wake();
5846}
5847
Vishnu Nairc519ff72021-01-21 08:23:08 -08005848void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
5849 if (changes.oldFocus) {
5850 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005851 if (focusedInputChannel) {
5852 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5853 "focus left window");
5854 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005855 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005856 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005857 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08005858 if (changes.newFocus) {
5859 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005860 }
5861
Prabir Pradhan99987712020-11-10 18:43:05 -08005862 // If a window has pointer capture, then it must have focus. We need to ensure that this
5863 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
5864 // If the window loses focus before it loses pointer capture, then the window can be in a state
5865 // where it has pointer capture but not focus, violating the contract. Therefore we must
5866 // dispatch the pointer capture event before the focus event. Since focus events are added to
5867 // the front of the queue (above), we add the pointer capture event to the front of the queue
5868 // after the focus events are added. This ensures the pointer capture event ends up at the
5869 // front.
5870 disablePointerCaptureForcedLocked();
5871
Vishnu Nairc519ff72021-01-21 08:23:08 -08005872 if (mFocusedDisplayId == changes.displayId) {
5873 notifyFocusChangedLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005874 }
5875}
Vishnu Nair958da932020-08-21 17:12:37 -07005876
Prabir Pradhan99987712020-11-10 18:43:05 -08005877void InputDispatcher::disablePointerCaptureForcedLocked() {
5878 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
5879 return;
5880 }
5881
5882 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
5883
5884 if (mFocusedWindowRequestedPointerCapture) {
5885 mFocusedWindowRequestedPointerCapture = false;
5886 setPointerCaptureLocked(false);
5887 }
5888
5889 if (!mWindowTokenWithPointerCapture) {
5890 // No need to send capture changes because no window has capture.
5891 return;
5892 }
5893
5894 if (mPendingEvent != nullptr) {
5895 // Move the pending event to the front of the queue. This will give the chance
5896 // for the pending event to be dropped if it is a captured event.
5897 mInboundQueue.push_front(mPendingEvent);
5898 mPendingEvent = nullptr;
5899 }
5900
5901 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
5902 false /* hasCapture */);
5903 mInboundQueue.push_front(std::move(entry));
5904}
5905
Prabir Pradhan99987712020-11-10 18:43:05 -08005906void InputDispatcher::setPointerCaptureLocked(bool enabled) {
5907 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5908 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
5909 commandEntry->enabled = enabled;
5910 postCommandLocked(std::move(commandEntry));
5911}
5912
5913void InputDispatcher::doSetPointerCaptureLockedInterruptible(
5914 android::inputdispatcher::CommandEntry* commandEntry) {
5915 mLock.unlock();
5916
5917 mPolicy->setPointerCapture(commandEntry->enabled);
5918
5919 mLock.lock();
5920}
5921
Garfield Tane84e6f92019-08-29 17:28:41 -07005922} // namespace android::inputdispatcher