blob: 0dfa027cc246e08e9b5464daf280ebd5704e0b6c [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
50#include "InputDispatcher.h"
51
Michael Wright2b3c3302018-03-02 17:19:13 +000052#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080053#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050054#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070055#include <binder/Binder.h>
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100056#include <binder/IServiceManager.h>
57#include <com/android/internal/compat/IPlatformCompatNative.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080058#include <input/InputDevice.h>
Michael Wright44753b12020-07-08 13:48:11 +010059#include <input/InputWindow.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070060#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000061#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070062#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010063#include <statslog.h>
64#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070065#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080066
Michael Wright44753b12020-07-08 13:48:11 +010067#include <cerrno>
68#include <cinttypes>
69#include <climits>
70#include <cstddef>
71#include <ctime>
72#include <queue>
73#include <sstream>
74
75#include "Connection.h"
76
Michael Wrightd02c5b62014-02-10 15:10:22 -080077#define INDENT " "
78#define INDENT2 " "
79#define INDENT3 " "
80#define INDENT4 " "
81
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080082using android::base::StringPrintf;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080083using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100084using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080085using android::os::InputEventInjectionResult;
86using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100087using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080088
Garfield Tane84e6f92019-08-29 17:28:41 -070089namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080090
91// Default input dispatching timeout if there is no focused application or paused window
92// from which to determine an appropriate dispatching timeout.
Siarhei Vishniakou70622952020-07-30 11:17:23 -050093constexpr std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT =
94 std::chrono::milliseconds(android::os::IInputConstants::DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
Michael Wrightd02c5b62014-02-10 15:10:22 -080095
96// Amount of time to allow for all pending events to be processed when an app switch
97// key is on the way. This is used to preempt input dispatch and drop input events
98// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000099constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800100
101// Amount of time to allow for an event to be dispatched (measured since its eventTime)
102// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000103constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104
Michael Wrightd02c5b62014-02-10 15:10:22 -0800105// 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 +0000106constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
107
108// Log a warning when an interception call takes longer than this to process.
109constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800110
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700111// Additional key latency in case a connection is still processing some motion events.
112// This will help with the case when a user touched a button that opens a new window,
113// and gives us the chance to dispatch the key to this new window.
114constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
115
Michael Wrightd02c5b62014-02-10 15:10:22 -0800116// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000117constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
118
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000119// Event log tags. See EventLogTags.logtags for reference
120constexpr int LOGTAG_INPUT_INTERACTION = 62000;
121constexpr int LOGTAG_INPUT_FOCUS = 62001;
122
Michael Wrightd02c5b62014-02-10 15:10:22 -0800123static inline nsecs_t now() {
124 return systemTime(SYSTEM_TIME_MONOTONIC);
125}
126
127static inline const char* toString(bool value) {
128 return value ? "true" : "false";
129}
130
131static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700132 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
133 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800134}
135
136static bool isValidKeyAction(int32_t action) {
137 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700138 case AKEY_EVENT_ACTION_DOWN:
139 case AKEY_EVENT_ACTION_UP:
140 return true;
141 default:
142 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800143 }
144}
145
146static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700147 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800148 ALOGE("Key event has invalid action code 0x%x", action);
149 return false;
150 }
151 return true;
152}
153
Michael Wright7b159c92015-05-14 14:48:03 +0100154static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800155 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700156 case AMOTION_EVENT_ACTION_DOWN:
157 case AMOTION_EVENT_ACTION_UP:
158 case AMOTION_EVENT_ACTION_CANCEL:
159 case AMOTION_EVENT_ACTION_MOVE:
160 case AMOTION_EVENT_ACTION_OUTSIDE:
161 case AMOTION_EVENT_ACTION_HOVER_ENTER:
162 case AMOTION_EVENT_ACTION_HOVER_MOVE:
163 case AMOTION_EVENT_ACTION_HOVER_EXIT:
164 case AMOTION_EVENT_ACTION_SCROLL:
165 return true;
166 case AMOTION_EVENT_ACTION_POINTER_DOWN:
167 case AMOTION_EVENT_ACTION_POINTER_UP: {
168 int32_t index = getMotionEventActionPointerIndex(action);
169 return index >= 0 && index < pointerCount;
170 }
171 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
172 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
173 return actionButton != 0;
174 default:
175 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800176 }
177}
178
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500179static int64_t millis(std::chrono::nanoseconds t) {
180 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
181}
182
Michael Wright7b159c92015-05-14 14:48:03 +0100183static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700184 const PointerProperties* pointerProperties) {
185 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186 ALOGE("Motion event has invalid action code 0x%x", action);
187 return false;
188 }
189 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000190 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700191 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800192 return false;
193 }
194 BitSet32 pointerIdBits;
195 for (size_t i = 0; i < pointerCount; i++) {
196 int32_t id = pointerProperties[i].id;
197 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700198 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
199 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800200 return false;
201 }
202 if (pointerIdBits.hasBit(id)) {
203 ALOGE("Motion event has duplicate pointer id %d", id);
204 return false;
205 }
206 pointerIdBits.markBit(id);
207 }
208 return true;
209}
210
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000211static std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800212 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000213 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214 }
215
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000216 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217 bool first = true;
218 Region::const_iterator cur = region.begin();
219 Region::const_iterator const tail = region.end();
220 while (cur != tail) {
221 if (first) {
222 first = false;
223 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800224 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800225 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800226 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800227 cur++;
228 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000229 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800230}
231
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500232static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
233 constexpr size_t maxEntries = 50; // max events to print
234 constexpr size_t skipBegin = maxEntries / 2;
235 const size_t skipEnd = queue.size() - maxEntries / 2;
236 // skip from maxEntries / 2 ... size() - maxEntries/2
237 // only print from 0 .. skipBegin and then from skipEnd .. size()
238
239 std::string dump;
240 for (size_t i = 0; i < queue.size(); i++) {
241 const DispatchEntry& entry = *queue[i];
242 if (i >= skipBegin && i < skipEnd) {
243 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
244 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
245 continue;
246 }
247 dump.append(INDENT4);
248 dump += entry.eventEntry->getDescription();
249 dump += StringPrintf(", seq=%" PRIu32
250 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
251 entry.seq, entry.targetFlags, entry.resolvedAction,
252 ns2ms(currentTime - entry.eventEntry->eventTime));
253 if (entry.deliveryTime != 0) {
254 // This entry was delivered, so add information on how long we've been waiting
255 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
256 }
257 dump.append("\n");
258 }
259 return dump;
260}
261
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700262/**
263 * Find the entry in std::unordered_map by key, and return it.
264 * If the entry is not found, return a default constructed entry.
265 *
266 * Useful when the entries are vectors, since an empty vector will be returned
267 * if the entry is not found.
268 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
269 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700270template <typename K, typename V>
271static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700272 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700273 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800274}
275
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700276/**
277 * Find the entry in std::unordered_map by value, and remove it.
278 * If more than one entry has the same value, then all matching
279 * key-value pairs will be removed.
280 *
281 * Return true if at least one value has been removed.
282 */
283template <typename K, typename V>
284static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
285 bool removed = false;
286 for (auto it = map.begin(); it != map.end();) {
287 if (it->second == value) {
288 it = map.erase(it);
289 removed = true;
290 } else {
291 it++;
292 }
293 }
294 return removed;
295}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800296
Vishnu Nair958da932020-08-21 17:12:37 -0700297/**
298 * Find the entry in std::unordered_map by key and return the value as an optional.
299 */
300template <typename K, typename V>
301static std::optional<V> getOptionalValueByKey(const std::unordered_map<K, V>& map, K key) {
302 auto it = map.find(key);
303 return it != map.end() ? std::optional<V>{it->second} : std::nullopt;
304}
305
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
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800318static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
319 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
320}
321
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000322static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700323 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000324 int32_t inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700325 if (inputTarget.useDefaultPointerTransform()) {
326 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700327 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
chaviw1ff3d1e2020-07-01 15:53:47 -0700328 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000329 }
330
331 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
332 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
333
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700334 std::vector<PointerCoords> pointerCoords;
335 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000336
337 // Use the first pointer information to normalize all other pointers. This could be any pointer
338 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700339 // uses the transform for the normalized pointer.
340 const ui::Transform& firstPointerTransform =
341 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
342 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000343
344 // Iterate through all pointers in the event to normalize against the first.
345 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
346 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
347 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700348 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000349
350 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700351 // First, apply the current pointer's transform to update the coordinates into
352 // window space.
353 pointerCoords[pointerIndex].transform(currTransform);
354 // Next, apply the inverse transform of the normalized coordinates so the
355 // current coordinates are transformed into the normalized coordinate space.
356 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000357 }
358
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700359 std::unique_ptr<MotionEntry> combinedMotionEntry =
360 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
361 motionEntry.deviceId, motionEntry.source,
362 motionEntry.displayId, motionEntry.policyFlags,
363 motionEntry.action, motionEntry.actionButton,
364 motionEntry.flags, motionEntry.metaState,
365 motionEntry.buttonState, motionEntry.classification,
366 motionEntry.edgeFlags, motionEntry.xPrecision,
367 motionEntry.yPrecision, motionEntry.xCursorPosition,
368 motionEntry.yCursorPosition, motionEntry.downTime,
369 motionEntry.pointerCount, motionEntry.pointerProperties,
370 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000371
372 if (motionEntry.injectionState) {
373 combinedMotionEntry->injectionState = motionEntry.injectionState;
374 combinedMotionEntry->injectionState->refCount += 1;
375 }
376
377 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700378 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
379 firstPointerTransform, inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000380 return dispatchEntry;
381}
382
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700383static void addGestureMonitors(const std::vector<Monitor>& monitors,
384 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
385 float yOffset = 0) {
386 if (monitors.empty()) {
387 return;
388 }
389 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
390 for (const Monitor& monitor : monitors) {
391 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
392 }
393}
394
Garfield Tan15601662020-09-22 15:32:38 -0700395static status_t openInputChannelPair(const std::string& name,
396 std::shared_ptr<InputChannel>& serverChannel,
397 std::unique_ptr<InputChannel>& clientChannel) {
398 std::unique_ptr<InputChannel> uniqueServerChannel;
399 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
400
401 serverChannel = std::move(uniqueServerChannel);
402 return result;
403}
404
Vishnu Nair958da932020-08-21 17:12:37 -0700405const char* InputDispatcher::typeToString(InputDispatcher::FocusResult result) {
406 switch (result) {
407 case InputDispatcher::FocusResult::OK:
408 return "Ok";
409 case InputDispatcher::FocusResult::NO_WINDOW:
410 return "Window not found";
411 case InputDispatcher::FocusResult::NOT_FOCUSABLE:
412 return "Window not focusable";
413 case InputDispatcher::FocusResult::NOT_VISIBLE:
414 return "Window not visible";
415 }
416}
417
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500418template <typename T>
419static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
420 if (lhs == nullptr && rhs == nullptr) {
421 return true;
422 }
423 if (lhs == nullptr || rhs == nullptr) {
424 return false;
425 }
426 return *lhs == *rhs;
427}
428
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000429static sp<IPlatformCompatNative> getCompatService() {
430 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
431 if (service == nullptr) {
432 ALOGE("Failed to link to compat service");
433 return nullptr;
434 }
435 return interface_cast<IPlatformCompatNative>(service);
436}
437
Michael Wrightd02c5b62014-02-10 15:10:22 -0800438// --- InputDispatcher ---
439
Garfield Tan00f511d2019-06-12 16:55:40 -0700440InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
441 : mPolicy(policy),
442 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700443 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800444 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700445 mAppSwitchSawKeyDown(false),
446 mAppSwitchDueTime(LONG_LONG_MAX),
447 mNextUnblockedEvent(nullptr),
448 mDispatchEnabled(false),
449 mDispatchFrozen(false),
450 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800451 // mInTouchMode will be initialized by the WindowManager to the default device config.
452 // To avoid leaking stack in case that call never comes, and for tests,
453 // initialize it here anyways.
454 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100455 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000456 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800457 mFocusedWindowRequestedPointerCapture(false),
458 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000459 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800460 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800461 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800462
Yi Kong9b14ac62018-07-17 13:48:38 -0700463 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800464
465 policy->getDispatcherConfiguration(&mConfig);
466}
467
468InputDispatcher::~InputDispatcher() {
469 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800470 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800471
472 resetKeyRepeatLocked();
473 releasePendingEventLocked();
474 drainInboundQueueLocked();
475 }
476
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700477 while (!mConnectionsByFd.empty()) {
478 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700479 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800480 }
481}
482
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700483status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700484 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700485 return ALREADY_EXISTS;
486 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700487 mThread = std::make_unique<InputThread>(
488 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
489 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700490}
491
492status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700493 if (mThread && mThread->isCallingThread()) {
494 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700495 return INVALID_OPERATION;
496 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700497 mThread.reset();
498 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700499}
500
Michael Wrightd02c5b62014-02-10 15:10:22 -0800501void InputDispatcher::dispatchOnce() {
502 nsecs_t nextWakeupTime = LONG_LONG_MAX;
503 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800504 std::scoped_lock _l(mLock);
505 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800506
507 // Run a dispatch loop if there are no pending commands.
508 // The dispatch loop might enqueue commands to run afterwards.
509 if (!haveCommandsLocked()) {
510 dispatchOnceInnerLocked(&nextWakeupTime);
511 }
512
513 // Run all pending commands if there are any.
514 // If any commands were run then force the next poll to wake up immediately.
515 if (runCommandsLockedInterruptible()) {
516 nextWakeupTime = LONG_LONG_MIN;
517 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800518
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700519 // If we are still waiting for ack on some events,
520 // we might have to wake up earlier to check if an app is anr'ing.
521 const nsecs_t nextAnrCheck = processAnrsLocked();
522 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
523
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800524 // We are about to enter an infinitely long sleep, because we have no commands or
525 // pending or queued events
526 if (nextWakeupTime == LONG_LONG_MAX) {
527 mDispatcherEnteredIdle.notify_all();
528 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800529 } // release lock
530
531 // Wait for callback or timeout or wake. (make sure we round up, not down)
532 nsecs_t currentTime = now();
533 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
534 mLooper->pollOnce(timeoutMillis);
535}
536
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700537/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500538 * Raise ANR if there is no focused window.
539 * Before the ANR is raised, do a final state check:
540 * 1. The currently focused application must be the same one we are waiting for.
541 * 2. Ensure we still don't have a focused window.
542 */
543void InputDispatcher::processNoFocusedWindowAnrLocked() {
544 // Check if the application that we are waiting for is still focused.
545 std::shared_ptr<InputApplicationHandle> focusedApplication =
546 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
547 if (focusedApplication == nullptr ||
548 focusedApplication->getApplicationToken() !=
549 mAwaitedFocusedApplication->getApplicationToken()) {
550 // Unexpected because we should have reset the ANR timer when focused application changed
551 ALOGE("Waited for a focused window, but focused application has already changed to %s",
552 focusedApplication->getName().c_str());
553 return; // The focused application has changed.
554 }
555
556 const sp<InputWindowHandle>& focusedWindowHandle =
557 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
558 if (focusedWindowHandle != nullptr) {
559 return; // We now have a focused window. No need for ANR.
560 }
561 onAnrLocked(mAwaitedFocusedApplication);
562}
563
564/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700565 * Check if any of the connections' wait queues have events that are too old.
566 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
567 * Return the time at which we should wake up next.
568 */
569nsecs_t InputDispatcher::processAnrsLocked() {
570 const nsecs_t currentTime = now();
571 nsecs_t nextAnrCheck = LONG_LONG_MAX;
572 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
573 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
574 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500575 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700576 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500577 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700578 return LONG_LONG_MIN;
579 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500580 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700581 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
582 }
583 }
584
585 // Check if any connection ANRs are due
586 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
587 if (currentTime < nextAnrCheck) { // most likely scenario
588 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
589 }
590
591 // If we reached here, we have an unresponsive connection.
592 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
593 if (connection == nullptr) {
594 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
595 return nextAnrCheck;
596 }
597 connection->responsive = false;
598 // Stop waking up for this unresponsive connection
599 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -0500600 onAnrLocked(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700601 return LONG_LONG_MIN;
602}
603
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500604std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700605 sp<InputWindowHandle> window = getWindowHandleLocked(token);
606 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500607 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700608 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500609 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700610}
611
Michael Wrightd02c5b62014-02-10 15:10:22 -0800612void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
613 nsecs_t currentTime = now();
614
Jeff Browndc5992e2014-04-11 01:27:26 -0700615 // Reset the key repeat timer whenever normal dispatch is suspended while the
616 // device is in a non-interactive state. This is to ensure that we abort a key
617 // repeat if the device is just coming out of sleep.
618 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800619 resetKeyRepeatLocked();
620 }
621
622 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
623 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100624 if (DEBUG_FOCUS) {
625 ALOGD("Dispatch frozen. Waiting some more.");
626 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800627 return;
628 }
629
630 // Optimize latency of app switches.
631 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
632 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
633 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
634 if (mAppSwitchDueTime < *nextWakeupTime) {
635 *nextWakeupTime = mAppSwitchDueTime;
636 }
637
638 // Ready to start a new event.
639 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700640 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700641 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800642 if (isAppSwitchDue) {
643 // The inbound queue is empty so the app switch key we were waiting
644 // for will never arrive. Stop waiting for it.
645 resetPendingAppSwitchLocked(false);
646 isAppSwitchDue = false;
647 }
648
649 // Synthesize a key repeat if appropriate.
650 if (mKeyRepeatState.lastKeyEntry) {
651 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
652 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
653 } else {
654 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
655 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
656 }
657 }
658 }
659
660 // Nothing to do if there is no pending event.
661 if (!mPendingEvent) {
662 return;
663 }
664 } else {
665 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700666 mPendingEvent = mInboundQueue.front();
667 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800668 traceInboundQueueLengthLocked();
669 }
670
671 // Poke user activity for this event.
672 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700673 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800674 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800675 }
676
677 // Now we have an event to dispatch.
678 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700679 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800680 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700681 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800682 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700683 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800684 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700685 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800686 }
687
688 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700689 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800690 }
691
692 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700693 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700694 const ConfigurationChangedEntry& typedEntry =
695 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700696 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700697 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700698 break;
699 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800700
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700701 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700702 const DeviceResetEntry& typedEntry =
703 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700704 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700705 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700706 break;
707 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800708
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100709 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700710 std::shared_ptr<FocusEntry> typedEntry =
711 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100712 dispatchFocusLocked(currentTime, typedEntry);
713 done = true;
714 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
715 break;
716 }
717
Prabir Pradhan99987712020-11-10 18:43:05 -0800718 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
719 const auto typedEntry =
720 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
721 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
722 done = true;
723 break;
724 }
725
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700726 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700727 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700728 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700729 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700730 resetPendingAppSwitchLocked(true);
731 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700732 } else if (dropReason == DropReason::NOT_DROPPED) {
733 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700734 }
735 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700736 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700737 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700738 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700739 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
740 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700741 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700742 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700743 break;
744 }
745
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700746 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700747 std::shared_ptr<MotionEntry> motionEntry =
748 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700749 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
750 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800751 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700752 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700753 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700754 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700755 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
756 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700757 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700758 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700759 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800760 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800761 }
762
763 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700764 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700765 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800766 }
Michael Wright3a981722015-06-10 15:26:13 +0100767 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800768
769 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700770 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800771 }
772}
773
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700774/**
775 * Return true if the events preceding this incoming motion event should be dropped
776 * Return false otherwise (the default behaviour)
777 */
778bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700779 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700780 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700781
782 // Optimize case where the current application is unresponsive and the user
783 // decides to touch a window in a different application.
784 // If the application takes too long to catch up then we drop all events preceding
785 // the touch into the other window.
786 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700787 int32_t displayId = motionEntry.displayId;
788 int32_t x = static_cast<int32_t>(
789 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
790 int32_t y = static_cast<int32_t>(
791 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
792 sp<InputWindowHandle> touchedWindowHandle =
793 findTouchedWindowAtLocked(displayId, x, y, nullptr);
794 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700795 touchedWindowHandle->getApplicationToken() !=
796 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700797 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700798 ALOGI("Pruning input queue because user touched a different application while waiting "
799 "for %s",
800 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700801 return true;
802 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700803
804 // Alternatively, maybe there's a gesture monitor that could handle this event
805 std::vector<TouchedMonitor> gestureMonitors =
806 findTouchedGestureMonitorsLocked(displayId, {});
807 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
808 sp<Connection> connection =
809 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000810 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700811 // This monitor could take more input. Drop all events preceding this
812 // event, so that gesture monitor could get a chance to receive the stream
813 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
814 "responsive gesture monitor that may handle the event",
815 mAwaitedFocusedApplication->getName().c_str());
816 return true;
817 }
818 }
819 }
820
821 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
822 // yet been processed by some connections, the dispatcher will wait for these motion
823 // events to be processed before dispatching the key event. This is because these motion events
824 // may cause a new window to be launched, which the user might expect to receive focus.
825 // To prevent waiting forever for such events, just send the key to the currently focused window
826 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
827 ALOGD("Received a new pointer down event, stop waiting for events to process and "
828 "just send the pending key event to the focused window.");
829 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700830 }
831 return false;
832}
833
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700834bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700835 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700836 mInboundQueue.push_back(std::move(newEntry));
837 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800838 traceInboundQueueLengthLocked();
839
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700840 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700841 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700842 // Optimize app switch latency.
843 // If the application takes too long to catch up then we drop all events preceding
844 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700845 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700846 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700847 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700848 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700849 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700850 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800851#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700852 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800853#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700854 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700855 mAppSwitchSawKeyDown = false;
856 needWake = true;
857 }
858 }
859 }
860 break;
861 }
862
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700863 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700864 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
865 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700866 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800867 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700868 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800869 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100870 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700871 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
872 break;
873 }
874 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -0800875 case EventEntry::Type::DEVICE_RESET:
876 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700877 // nothing to do
878 break;
879 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800880 }
881
882 return needWake;
883}
884
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700885void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700886 mRecentQueue.push_back(entry);
887 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700888 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800889 }
890}
891
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700892sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700893 int32_t y, TouchState* touchState,
894 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700895 bool addPortalWindows) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700896 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
897 LOG_ALWAYS_FATAL(
898 "Must provide a valid touch state if adding portal windows or outside targets");
899 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800900 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700901 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800902 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800903 const InputWindowInfo* windowInfo = windowHandle->getInfo();
904 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100905 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800906
907 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100908 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
909 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
910 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800911 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800912 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700913 if (portalToDisplayId != ADISPLAY_ID_NONE &&
914 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800915 if (addPortalWindows) {
916 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700917 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800918 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700919 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700920 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800921 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800922 // Found window.
923 return windowHandle;
924 }
925 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800926
Michael Wright44753b12020-07-08 13:48:11 +0100927 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700928 touchState->addOrUpdateWindow(windowHandle,
929 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
930 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800931 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800932 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800933 }
934 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700935 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800936}
937
Garfield Tane84e6f92019-08-29 17:28:41 -0700938std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700939 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000940 std::vector<TouchedMonitor> touchedMonitors;
941
942 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
943 addGestureMonitors(monitors, touchedMonitors);
944 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
945 const InputWindowInfo* windowInfo = portalWindow->getInfo();
946 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700947 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
948 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000949 }
950 return touchedMonitors;
951}
952
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700953void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800954 const char* reason;
955 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700956 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800957#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700958 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800959#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700960 reason = "inbound event was dropped because the policy consumed it";
961 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700962 case DropReason::DISABLED:
963 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700964 ALOGI("Dropped event because input dispatch is disabled.");
965 }
966 reason = "inbound event was dropped because input dispatch is disabled";
967 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700968 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700969 ALOGI("Dropped event because of pending overdue app switch.");
970 reason = "inbound event was dropped because of pending overdue app switch";
971 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700972 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700973 ALOGI("Dropped event because the current application is not responding and the user "
974 "has started interacting with a different application.");
975 reason = "inbound event was dropped because the current application is not responding "
976 "and the user has started interacting with a different application";
977 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700978 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700979 ALOGI("Dropped event because it is stale.");
980 reason = "inbound event was dropped because it is stale";
981 break;
Prabir Pradhan99987712020-11-10 18:43:05 -0800982 case DropReason::NO_POINTER_CAPTURE:
983 ALOGI("Dropped event because there is no window with Pointer Capture.");
984 reason = "inbound event was dropped because there is no window with Pointer Capture";
985 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700986 case DropReason::NOT_DROPPED: {
987 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700988 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700989 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800990 }
991
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700992 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700993 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800994 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
995 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700996 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800997 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700998 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700999 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1000 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001001 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1002 synthesizeCancelationEventsForAllConnectionsLocked(options);
1003 } else {
1004 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1005 synthesizeCancelationEventsForAllConnectionsLocked(options);
1006 }
1007 break;
1008 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001009 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1010 break;
1011 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001012 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001013 case EventEntry::Type::CONFIGURATION_CHANGED:
1014 case EventEntry::Type::DEVICE_RESET: {
1015 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
1016 break;
1017 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001018 }
1019}
1020
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001021static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001022 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1023 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001024}
1025
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001026bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1027 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1028 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1029 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001030}
1031
1032bool InputDispatcher::isAppSwitchPendingLocked() {
1033 return mAppSwitchDueTime != LONG_LONG_MAX;
1034}
1035
1036void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1037 mAppSwitchDueTime = LONG_LONG_MAX;
1038
1039#if DEBUG_APP_SWITCH
1040 if (handled) {
1041 ALOGD("App switch has arrived.");
1042 } else {
1043 ALOGD("App switch was abandoned.");
1044 }
1045#endif
1046}
1047
Michael Wrightd02c5b62014-02-10 15:10:22 -08001048bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001049 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001050}
1051
1052bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001053 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001054 return false;
1055 }
1056
1057 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001058 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001059 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001060 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001061 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001062
1063 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001064 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001065 return true;
1066}
1067
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001068void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1069 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001070}
1071
1072void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001073 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001074 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001075 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001076 releaseInboundEventLocked(entry);
1077 }
1078 traceInboundQueueLengthLocked();
1079}
1080
1081void InputDispatcher::releasePendingEventLocked() {
1082 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001083 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001084 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001085 }
1086}
1087
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001088void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001089 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001090 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001091#if DEBUG_DISPATCH_CYCLE
1092 ALOGD("Injected inbound event was dropped.");
1093#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001094 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001095 }
1096 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001097 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001098 }
1099 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001100}
1101
1102void InputDispatcher::resetKeyRepeatLocked() {
1103 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001104 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001105 }
1106}
1107
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001108std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1109 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001110
Michael Wright2e732952014-09-24 13:26:59 -07001111 uint32_t policyFlags = entry->policyFlags &
1112 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001113
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001114 std::shared_ptr<KeyEntry> newEntry =
1115 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1116 entry->source, entry->displayId, policyFlags, entry->action,
1117 entry->flags, entry->keyCode, entry->scanCode,
1118 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001119
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001120 newEntry->syntheticRepeat = true;
1121 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001122 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001123 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001124}
1125
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001126bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001127 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001128#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001129 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130#endif
1131
1132 // Reset key repeating in case a keyboard device was added or removed or something.
1133 resetKeyRepeatLocked();
1134
1135 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001136 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1137 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001138 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001139 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001140 return true;
1141}
1142
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001143bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1144 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001145#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001146 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1147 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001148#endif
1149
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001150 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001151 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001152 synthesizeCancelationEventsForAllConnectionsLocked(options);
1153 return true;
1154}
1155
Vishnu Nairad321cd2020-08-20 16:40:21 -07001156void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001157 std::string_view reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001158 if (mPendingEvent != nullptr) {
1159 // Move the pending event to the front of the queue. This will give the chance
1160 // for the pending event to get dispatched to the newly focused window
1161 mInboundQueue.push_front(mPendingEvent);
1162 mPendingEvent = nullptr;
1163 }
1164
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001165 std::unique_ptr<FocusEntry> focusEntry =
1166 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1167 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001168
1169 // This event should go to the front of the queue, but behind all other focus events
1170 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001171 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001172 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001173 [](const std::shared_ptr<EventEntry>& event) {
1174 return event->type == EventEntry::Type::FOCUS;
1175 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001176
1177 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001178 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001179}
1180
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001181void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001182 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001183 if (channel == nullptr) {
1184 return; // Window has gone away
1185 }
1186 InputTarget target;
1187 target.inputChannel = channel;
1188 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1189 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001190 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1191 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001192 std::string reason = std::string("reason=").append(entry->reason);
1193 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001194 dispatchEventLocked(currentTime, entry, {target});
1195}
1196
Prabir Pradhan99987712020-11-10 18:43:05 -08001197void InputDispatcher::dispatchPointerCaptureChangedLocked(
1198 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1199 DropReason& dropReason) {
1200 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
1201 if (entry->pointerCaptureEnabled == haveWindowWithPointerCapture) {
1202 LOG_ALWAYS_FATAL_IF(mFocusedWindowRequestedPointerCapture,
1203 "The Pointer Capture state has already been dispatched to the window.");
1204 // Pointer capture was already forcefully disabled because of focus change.
1205 dropReason = DropReason::NOT_DROPPED;
1206 return;
1207 }
1208
1209 // Set drop reason for early returns
1210 dropReason = DropReason::NO_POINTER_CAPTURE;
1211
1212 sp<IBinder> token;
1213 if (entry->pointerCaptureEnabled) {
1214 // Enable Pointer Capture
1215 if (!mFocusedWindowRequestedPointerCapture) {
1216 // This can happen if a window requests capture and immediately releases capture.
1217 ALOGW("No window requested Pointer Capture.");
1218 return;
1219 }
1220 token = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
1221 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1222 mWindowTokenWithPointerCapture = token;
1223 } else {
1224 // Disable Pointer Capture
1225 token = mWindowTokenWithPointerCapture;
1226 mWindowTokenWithPointerCapture = nullptr;
1227 mFocusedWindowRequestedPointerCapture = false;
1228 }
1229
1230 auto channel = getInputChannelLocked(token);
1231 if (channel == nullptr) {
1232 // Window has gone away, clean up Pointer Capture state.
1233 mWindowTokenWithPointerCapture = nullptr;
1234 mFocusedWindowRequestedPointerCapture = false;
1235 return;
1236 }
1237 InputTarget target;
1238 target.inputChannel = channel;
1239 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1240 entry->dispatchInProgress = true;
1241 dispatchEventLocked(currentTime, entry, {target});
1242
1243 dropReason = DropReason::NOT_DROPPED;
1244}
1245
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001246bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001247 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001248 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001249 if (!entry->dispatchInProgress) {
1250 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1251 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1252 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1253 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001254 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001255 // We have seen two identical key downs in a row which indicates that the device
1256 // driver is automatically generating key repeats itself. We take note of the
1257 // repeat here, but we disable our own next key repeat timer since it is clear that
1258 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001259 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1260 // Make sure we don't get key down from a different device. If a different
1261 // device Id has same key pressed down, the new device Id will replace the
1262 // current one to hold the key repeat with repeat count reset.
1263 // In the future when got a KEY_UP on the device id, drop it and do not
1264 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001265 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1266 resetKeyRepeatLocked();
1267 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1268 } else {
1269 // Not a repeat. Save key down state in case we do see a repeat later.
1270 resetKeyRepeatLocked();
1271 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1272 }
1273 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001274 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1275 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001276 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001277#if DEBUG_INBOUND_EVENT_DETAILS
1278 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1279#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001280 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001281 resetKeyRepeatLocked();
1282 }
1283
1284 if (entry->repeatCount == 1) {
1285 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1286 } else {
1287 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1288 }
1289
1290 entry->dispatchInProgress = true;
1291
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001292 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001293 }
1294
1295 // Handle case where the policy asked us to try again later last time.
1296 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1297 if (currentTime < entry->interceptKeyWakeupTime) {
1298 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1299 *nextWakeupTime = entry->interceptKeyWakeupTime;
1300 }
1301 return false; // wait until next wakeup
1302 }
1303 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1304 entry->interceptKeyWakeupTime = 0;
1305 }
1306
1307 // Give the policy a chance to intercept the key.
1308 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1309 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001310 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001311 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001312 sp<IBinder> focusedWindowToken =
1313 getValueByKey(mFocusedWindowTokenByDisplay, getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001314 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001315 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001316 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001317 return false; // wait for the command to run
1318 } else {
1319 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1320 }
1321 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001322 if (*dropReason == DropReason::NOT_DROPPED) {
1323 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001324 }
1325 }
1326
1327 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001328 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001329 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001330 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1331 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001332 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001333 return true;
1334 }
1335
1336 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001337 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001338 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001339 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001340 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001341 return false;
1342 }
1343
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001344 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001345 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001346 return true;
1347 }
1348
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001349 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001350 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001351
1352 // Dispatch the key.
1353 dispatchEventLocked(currentTime, entry, inputTargets);
1354 return true;
1355}
1356
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001357void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001358#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001359 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001360 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1361 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001362 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1363 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1364 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001365#endif
1366}
1367
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001368bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001369 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001370 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001371 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001372 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001373 entry->dispatchInProgress = true;
1374
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001375 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001376 }
1377
1378 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001379 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001380 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001381 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1382 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001383 return true;
1384 }
1385
1386 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1387
1388 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001389 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001390
1391 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001392 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001393 if (isPointerEvent) {
1394 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001395 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001396 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001397 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001398 } else {
1399 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001400 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001401 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001402 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001403 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001404 return false;
1405 }
1406
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001407 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001408 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001409 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1410 return true;
1411 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001412 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001413 CancelationOptions::Mode mode(isPointerEvent
1414 ? CancelationOptions::CANCEL_POINTER_EVENTS
1415 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1416 CancelationOptions options(mode, "input event injection failed");
1417 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001418 return true;
1419 }
1420
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001421 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001422 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001423
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001424 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001425 std::unordered_map<int32_t, TouchState>::iterator it =
1426 mTouchStatesByDisplay.find(entry->displayId);
1427 if (it != mTouchStatesByDisplay.end()) {
1428 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001429 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001430 // The event has gone through these portal windows, so we add monitoring targets of
1431 // the corresponding displays as well.
1432 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001433 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001434 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001435 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001436 }
1437 }
1438 }
1439 }
1440
Michael Wrightd02c5b62014-02-10 15:10:22 -08001441 // Dispatch the motion.
1442 if (conflictingPointerActions) {
1443 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001444 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001445 synthesizeCancelationEventsForAllConnectionsLocked(options);
1446 }
1447 dispatchEventLocked(currentTime, entry, inputTargets);
1448 return true;
1449}
1450
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001451void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001452#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001453 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001454 ", policyFlags=0x%x, "
1455 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1456 "metaState=0x%x, buttonState=0x%x,"
1457 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001458 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1459 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1460 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001461
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001462 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001463 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001464 "x=%f, y=%f, pressure=%f, size=%f, "
1465 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1466 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001467 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1468 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1469 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1470 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1471 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1472 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1473 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1474 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1475 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1476 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001477 }
1478#endif
1479}
1480
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001481void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1482 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001483 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001484 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001485#if DEBUG_DISPATCH_CYCLE
1486 ALOGD("dispatchEventToCurrentInputTargets");
1487#endif
1488
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001489 updateInteractionTokensLocked(*eventEntry, inputTargets);
1490
Michael Wrightd02c5b62014-02-10 15:10:22 -08001491 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1492
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001493 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001494
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001495 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001496 sp<Connection> connection =
1497 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001498 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001499 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001500 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001501 if (DEBUG_FOCUS) {
1502 ALOGD("Dropping event delivery to target with channel '%s' because it "
1503 "is no longer registered with the input dispatcher.",
1504 inputTarget.inputChannel->getName().c_str());
1505 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001506 }
1507 }
1508}
1509
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001510void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1511 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1512 // If the policy decides to close the app, we will get a channel removal event via
1513 // unregisterInputChannel, and will clean up the connection that way. We are already not
1514 // sending new pointers to the connection when it blocked, but focused events will continue to
1515 // pile up.
1516 ALOGW("Canceling events for %s because it is unresponsive",
1517 connection->inputChannel->getName().c_str());
1518 if (connection->status == Connection::STATUS_NORMAL) {
1519 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1520 "application not responding");
1521 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001522 }
1523}
1524
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001525void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001526 if (DEBUG_FOCUS) {
1527 ALOGD("Resetting ANR timeouts.");
1528 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001529
1530 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001531 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001532 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001533}
1534
Tiger Huang721e26f2018-07-24 22:26:19 +08001535/**
1536 * Get the display id that the given event should go to. If this event specifies a valid display id,
1537 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1538 * Focused display is the display that the user most recently interacted with.
1539 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001540int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001541 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001542 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001543 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001544 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1545 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001546 break;
1547 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001548 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001549 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1550 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001551 break;
1552 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001553 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001554 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001555 case EventEntry::Type::CONFIGURATION_CHANGED:
1556 case EventEntry::Type::DEVICE_RESET: {
1557 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001558 return ADISPLAY_ID_NONE;
1559 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001560 }
1561 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1562}
1563
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001564bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1565 const char* focusedWindowName) {
1566 if (mAnrTracker.empty()) {
1567 // already processed all events that we waited for
1568 mKeyIsWaitingForEventsTimeout = std::nullopt;
1569 return false;
1570 }
1571
1572 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1573 // Start the timer
1574 ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
1575 "focus to change",
1576 focusedWindowName);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001577 mKeyIsWaitingForEventsTimeout = currentTime +
1578 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1579 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001580 return true;
1581 }
1582
1583 // We still have pending events, and already started the timer
1584 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1585 return true; // Still waiting
1586 }
1587
1588 // Waited too long, and some connection still hasn't processed all motions
1589 // Just send the key to the focused window
1590 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1591 focusedWindowName);
1592 mKeyIsWaitingForEventsTimeout = std::nullopt;
1593 return false;
1594}
1595
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001596InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1597 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1598 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001599 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001600
Tiger Huang721e26f2018-07-24 22:26:19 +08001601 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001602 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001603 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001604 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1605
Michael Wrightd02c5b62014-02-10 15:10:22 -08001606 // If there is no currently focused window and no focused application
1607 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001608 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1609 ALOGI("Dropping %s event because there is no focused window or focused application in "
1610 "display %" PRId32 ".",
1611 EventEntry::typeToString(entry.type), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001612 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001613 }
1614
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001615 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1616 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1617 // start interacting with another application via touch (app switch). This code can be removed
1618 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1619 // an app is expected to have a focused window.
1620 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1621 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1622 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001623 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1624 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1625 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001626 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001627 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001628 ALOGW("Waiting because no window has focus but %s may eventually add a "
1629 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001630 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001631 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001632 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001633 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1634 // Already raised ANR. Drop the event
1635 ALOGE("Dropping %s event because there is no focused window",
1636 EventEntry::typeToString(entry.type));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001637 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001638 } else {
1639 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001640 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001641 }
1642 }
1643
1644 // we have a valid, non-null focused window
1645 resetNoFocusedWindowTimeoutLocked();
1646
Michael Wrightd02c5b62014-02-10 15:10:22 -08001647 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001648 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001649 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001650 }
1651
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001652 if (focusedWindowHandle->getInfo()->paused) {
1653 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001654 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001655 }
1656
1657 // If the event is a key event, then we must wait for all previous events to
1658 // complete before delivering it because previous events may have the
1659 // side-effect of transferring focus to a different window and we want to
1660 // ensure that the following keys are sent to the new window.
1661 //
1662 // Suppose the user touches a button in a window then immediately presses "A".
1663 // If the button causes a pop-up window to appear then we want to ensure that
1664 // the "A" key is delivered to the new pop-up window. This is because users
1665 // often anticipate pending UI changes when typing on a keyboard.
1666 // To obtain this behavior, we must serialize key events with respect to all
1667 // prior input events.
1668 if (entry.type == EventEntry::Type::KEY) {
1669 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1670 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001671 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001672 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001673 }
1674
1675 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001676 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001677 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1678 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001679
1680 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001681 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001682}
1683
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001684/**
1685 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1686 * that are currently unresponsive.
1687 */
1688std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1689 const std::vector<TouchedMonitor>& monitors) const {
1690 std::vector<TouchedMonitor> responsiveMonitors;
1691 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1692 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1693 sp<Connection> connection = getConnectionLocked(
1694 monitor.monitor.inputChannel->getConnectionToken());
1695 if (connection == nullptr) {
1696 ALOGE("Could not find connection for monitor %s",
1697 monitor.monitor.inputChannel->getName().c_str());
1698 return false;
1699 }
1700 if (!connection->responsive) {
1701 ALOGW("Unresponsive monitor %s will not get the new gesture",
1702 connection->inputChannel->getName().c_str());
1703 return false;
1704 }
1705 return true;
1706 });
1707 return responsiveMonitors;
1708}
1709
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001710InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1711 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1712 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001713 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001714 enum InjectionPermission {
1715 INJECTION_PERMISSION_UNKNOWN,
1716 INJECTION_PERMISSION_GRANTED,
1717 INJECTION_PERMISSION_DENIED
1718 };
1719
Michael Wrightd02c5b62014-02-10 15:10:22 -08001720 // For security reasons, we defer updating the touch state until we are sure that
1721 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001722 int32_t displayId = entry.displayId;
1723 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001724 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1725
1726 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001727 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001728 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001729 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1730 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001731
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001732 // Copy current touch state into tempTouchState.
1733 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1734 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001735 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001736 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001737 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1738 mTouchStatesByDisplay.find(displayId);
1739 if (oldStateIt != mTouchStatesByDisplay.end()) {
1740 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001741 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001742 }
1743
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001744 bool isSplit = tempTouchState.split;
1745 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1746 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1747 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001748 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1749 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1750 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1751 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1752 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001753 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001754 bool wrongDevice = false;
1755 if (newGesture) {
1756 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001757 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001758 ALOGI("Dropping event because a pointer for a different device is already down "
1759 "in display %" PRId32,
1760 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001761 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001762 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001763 switchedDevice = false;
1764 wrongDevice = true;
1765 goto Failed;
1766 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001767 tempTouchState.reset();
1768 tempTouchState.down = down;
1769 tempTouchState.deviceId = entry.deviceId;
1770 tempTouchState.source = entry.source;
1771 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001772 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001773 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001774 ALOGI("Dropping move event because a pointer for a different device is already active "
1775 "in display %" PRId32,
1776 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001777 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001778 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001779 switchedDevice = false;
1780 wrongDevice = true;
1781 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001782 }
1783
1784 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1785 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1786
Garfield Tan00f511d2019-06-12 16:55:40 -07001787 int32_t x;
1788 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001789 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001790 // Always dispatch mouse events to cursor position.
1791 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001792 x = int32_t(entry.xCursorPosition);
1793 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001794 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001795 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1796 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001797 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001798 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001799 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001800 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1801 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001802
1803 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001804 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001805 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001806
Michael Wrightd02c5b62014-02-10 15:10:22 -08001807 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001808 if (newTouchedWindowHandle != nullptr &&
1809 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001810 // New window supports splitting, but we should never split mouse events.
1811 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001812 } else if (isSplit) {
1813 // New window does not support splitting but we have already split events.
1814 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001815 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001816 }
1817
1818 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001819 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001820 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001821 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001822 }
1823
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001824 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1825 ALOGI("Not sending touch event to %s because it is paused",
1826 newTouchedWindowHandle->getName().c_str());
1827 newTouchedWindowHandle = nullptr;
1828 }
1829
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001830 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001831 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001832 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1833 if (!isResponsive) {
1834 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001835 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1836 newTouchedWindowHandle = nullptr;
1837 }
1838 }
1839
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001840 // Drop events that can't be trusted due to occlusion
1841 if (newTouchedWindowHandle != nullptr &&
1842 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1843 TouchOcclusionInfo occlusionInfo =
1844 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001845 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001846 if (DEBUG_TOUCH_OCCLUSION) {
1847 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1848 for (const auto& log : occlusionInfo.debugInfo) {
1849 ALOGD("%s", log.c_str());
1850 }
1851 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001852 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
1853 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1854 ALOGW("Dropping untrusted touch event due to %s/%d",
1855 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1856 newTouchedWindowHandle = nullptr;
1857 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001858 }
1859 }
1860
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001861 // Also don't send the new touch event to unresponsive gesture monitors
1862 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1863
Michael Wright3dd60e22019-03-27 22:06:44 +00001864 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1865 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001866 "(%d, %d) in display %" PRId32 ".",
1867 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001868 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001869 goto Failed;
1870 }
1871
1872 if (newTouchedWindowHandle != nullptr) {
1873 // Set target flags.
1874 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1875 if (isSplit) {
1876 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001877 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001878 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1879 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1880 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1881 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1882 }
1883
1884 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07001885 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
1886 newHoverWindowHandle = nullptr;
1887 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001888 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00001889 }
1890
1891 // Update the temporary touch state.
1892 BitSet32 pointerIds;
1893 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001894 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001895 pointerIds.markBit(pointerId);
1896 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001897 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001898 }
1899
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001900 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001901 } else {
1902 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1903
1904 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001905 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001906 if (DEBUG_FOCUS) {
1907 ALOGD("Dropping event because the pointer is not down or we previously "
1908 "dropped the pointer down event in display %" PRId32,
1909 displayId);
1910 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001911 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001912 goto Failed;
1913 }
1914
1915 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001916 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001917 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001918 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1919 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920
1921 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001922 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07001923 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001924 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1925 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001926 if (DEBUG_FOCUS) {
1927 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1928 oldTouchedWindowHandle->getName().c_str(),
1929 newTouchedWindowHandle->getName().c_str(), displayId);
1930 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001931 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001932 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1933 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1934 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001935
1936 // Make a slippery entrance into the new window.
1937 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1938 isSplit = true;
1939 }
1940
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001941 int32_t targetFlags =
1942 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001943 if (isSplit) {
1944 targetFlags |= InputTarget::FLAG_SPLIT;
1945 }
1946 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1947 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10001948 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1949 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001950 }
1951
1952 BitSet32 pointerIds;
1953 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001954 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001955 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001956 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001957 }
1958 }
1959 }
1960
1961 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07001962 // Let the previous window know that the hover sequence is over, unless we already did it
1963 // when dispatching it as is to newTouchedWindowHandle.
1964 if (mLastHoverWindowHandle != nullptr &&
1965 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
1966 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001967#if DEBUG_HOVER
1968 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001969 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001970#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001971 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1972 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001973 }
1974
Garfield Tandf26e862020-07-01 20:18:19 -07001975 // Let the new window know that the hover sequence is starting, unless we already did it
1976 // when dispatching it as is to newTouchedWindowHandle.
1977 if (newHoverWindowHandle != nullptr &&
1978 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
1979 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001980#if DEBUG_HOVER
1981 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001982 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001983#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001984 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1985 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1986 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001987 }
1988 }
1989
1990 // Check permission to inject into all touched foreground windows and ensure there
1991 // is at least one touched foreground window.
1992 {
1993 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001994 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001995 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1996 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001997 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001998 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001999 injectionPermission = INJECTION_PERMISSION_DENIED;
2000 goto Failed;
2001 }
2002 }
2003 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002004 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002005 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002006 ALOGI("Dropping event because there is no touched foreground window in display "
2007 "%" PRId32 " or gesture monitor to receive it.",
2008 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002009 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002010 goto Failed;
2011 }
2012
2013 // Permission granted to injection into all touched foreground windows.
2014 injectionPermission = INJECTION_PERMISSION_GRANTED;
2015 }
2016
2017 // Check whether windows listening for outside touches are owned by the same UID. If it is
2018 // set the policy flag that we will not reveal coordinate information to this window.
2019 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2020 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002021 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002022 if (foregroundWindowHandle) {
2023 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002024 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002025 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2026 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
2027 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002028 tempTouchState.addOrUpdateWindow(inputWindowHandle,
2029 InputTarget::FLAG_ZERO_COORDS,
2030 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002031 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002032 }
2033 }
2034 }
2035 }
2036
Michael Wrightd02c5b62014-02-10 15:10:22 -08002037 // If this is the first pointer going down and the touched window has a wallpaper
2038 // then also add the touched wallpaper windows so they are locked in for the duration
2039 // of the touch gesture.
2040 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2041 // engine only supports touch events. We would need to add a mechanism similar
2042 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2043 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2044 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002045 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002046 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07002047 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002048 getWindowHandlesLocked(displayId);
2049 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002050 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002051 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01002052 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002053 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002054 .addOrUpdateWindow(windowHandle,
2055 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2056 InputTarget::
2057 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2058 InputTarget::FLAG_DISPATCH_AS_IS,
2059 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002060 }
2061 }
2062 }
2063 }
2064
2065 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002066 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002068 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002069 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002070 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002071 }
2072
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002073 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002074 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002075 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002076 }
2077
Michael Wrightd02c5b62014-02-10 15:10:22 -08002078 // Drop the outside or hover touch windows since we will not care about them
2079 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002080 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002081
2082Failed:
2083 // Check injection permission once and for all.
2084 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002085 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002086 injectionPermission = INJECTION_PERMISSION_GRANTED;
2087 } else {
2088 injectionPermission = INJECTION_PERMISSION_DENIED;
2089 }
2090 }
2091
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002092 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2093 return injectionResult;
2094 }
2095
Michael Wrightd02c5b62014-02-10 15:10:22 -08002096 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002097 if (!wrongDevice) {
2098 if (switchedDevice) {
2099 if (DEBUG_FOCUS) {
2100 ALOGD("Conflicting pointer actions: Switched to a different device.");
2101 }
2102 *outConflictingPointerActions = true;
2103 }
2104
2105 if (isHoverAction) {
2106 // Started hovering, therefore no longer down.
2107 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002108 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002109 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2110 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002111 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002112 *outConflictingPointerActions = true;
2113 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002114 tempTouchState.reset();
2115 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2116 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2117 tempTouchState.deviceId = entry.deviceId;
2118 tempTouchState.source = entry.source;
2119 tempTouchState.displayId = displayId;
2120 }
2121 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2122 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2123 // All pointers up or canceled.
2124 tempTouchState.reset();
2125 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2126 // First pointer went down.
2127 if (oldState && oldState->down) {
2128 if (DEBUG_FOCUS) {
2129 ALOGD("Conflicting pointer actions: Down received while already down.");
2130 }
2131 *outConflictingPointerActions = true;
2132 }
2133 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2134 // One pointer went up.
2135 if (isSplit) {
2136 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2137 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002138
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002139 for (size_t i = 0; i < tempTouchState.windows.size();) {
2140 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2141 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2142 touchedWindow.pointerIds.clearBit(pointerId);
2143 if (touchedWindow.pointerIds.isEmpty()) {
2144 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2145 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002146 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002147 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002148 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002149 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002150 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002151 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002152
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002153 // Save changes unless the action was scroll in which case the temporary touch
2154 // state was only valid for this one action.
2155 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2156 if (tempTouchState.displayId >= 0) {
2157 mTouchStatesByDisplay[displayId] = tempTouchState;
2158 } else {
2159 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002160 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002161 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002162
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002163 // Update hover state.
2164 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002165 }
2166
Michael Wrightd02c5b62014-02-10 15:10:22 -08002167 return injectionResult;
2168}
2169
2170void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002171 int32_t targetFlags, BitSet32 pointerIds,
2172 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002173 std::vector<InputTarget>::iterator it =
2174 std::find_if(inputTargets.begin(), inputTargets.end(),
2175 [&windowHandle](const InputTarget& inputTarget) {
2176 return inputTarget.inputChannel->getConnectionToken() ==
2177 windowHandle->getToken();
2178 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002179
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002180 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002181
2182 if (it == inputTargets.end()) {
2183 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002184 std::shared_ptr<InputChannel> inputChannel =
2185 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002186 if (inputChannel == nullptr) {
2187 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2188 return;
2189 }
2190 inputTarget.inputChannel = inputChannel;
2191 inputTarget.flags = targetFlags;
2192 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2193 inputTargets.push_back(inputTarget);
2194 it = inputTargets.end() - 1;
2195 }
2196
2197 ALOG_ASSERT(it->flags == targetFlags);
2198 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2199
chaviw1ff3d1e2020-07-01 15:53:47 -07002200 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002201}
2202
Michael Wright3dd60e22019-03-27 22:06:44 +00002203void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002204 int32_t displayId, float xOffset,
2205 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002206 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2207 mGlobalMonitorsByDisplay.find(displayId);
2208
2209 if (it != mGlobalMonitorsByDisplay.end()) {
2210 const std::vector<Monitor>& monitors = it->second;
2211 for (const Monitor& monitor : monitors) {
2212 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002213 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002214 }
2215}
2216
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002217void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2218 float yOffset,
2219 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002220 InputTarget target;
2221 target.inputChannel = monitor.inputChannel;
2222 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002223 ui::Transform t;
2224 t.set(xOffset, yOffset);
2225 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002226 inputTargets.push_back(target);
2227}
2228
Michael Wrightd02c5b62014-02-10 15:10:22 -08002229bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002230 const InjectionState* injectionState) {
2231 if (injectionState &&
2232 (windowHandle == nullptr ||
2233 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2234 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002235 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002236 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002237 "owned by uid %d",
2238 injectionState->injectorPid, injectionState->injectorUid,
2239 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002240 } else {
2241 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002242 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002243 }
2244 return false;
2245 }
2246 return true;
2247}
2248
Robert Carrc9bf1d32020-04-13 17:21:08 -07002249/**
2250 * Indicate whether one window handle should be considered as obscuring
2251 * another window handle. We only check a few preconditions. Actually
2252 * checking the bounds is left to the caller.
2253 */
2254static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2255 const sp<InputWindowHandle>& otherHandle) {
2256 // Compare by token so cloned layers aren't counted
2257 if (haveSameToken(windowHandle, otherHandle)) {
2258 return false;
2259 }
2260 auto info = windowHandle->getInfo();
2261 auto otherInfo = otherHandle->getInfo();
2262 if (!otherInfo->visible) {
2263 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002264 } else if (otherInfo->alpha == 0 &&
2265 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2266 // Those act as if they were invisible, so we don't need to flag them.
2267 // We do want to potentially flag touchable windows even if they have 0
2268 // opacity, since they can consume touches and alter the effects of the
2269 // user interaction (eg. apps that rely on
2270 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2271 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2272 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002273 } else if (info->ownerUid == otherInfo->ownerUid) {
2274 // If ownerUid is the same we don't generate occlusion events as there
2275 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002276 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002277 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002278 return false;
2279 } else if (otherInfo->displayId != info->displayId) {
2280 return false;
2281 }
2282 return true;
2283}
2284
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002285/**
2286 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2287 * untrusted, one should check:
2288 *
2289 * 1. If result.hasBlockingOcclusion is true.
2290 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2291 * BLOCK_UNTRUSTED.
2292 *
2293 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2294 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2295 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2296 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2297 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2298 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2299 *
2300 * If neither of those is true, then it means the touch can be allowed.
2301 */
2302InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2303 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002304 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2305 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002306 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2307 TouchOcclusionInfo info;
2308 info.hasBlockingOcclusion = false;
2309 info.obscuringOpacity = 0;
2310 info.obscuringUid = -1;
2311 std::map<int32_t, float> opacityByUid;
2312 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2313 if (windowHandle == otherHandle) {
2314 break; // All future windows are below us. Exit early.
2315 }
2316 const InputWindowInfo* otherInfo = otherHandle->getInfo();
2317 if (canBeObscuredBy(windowHandle, otherHandle) &&
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002318 windowInfo->ownerUid != otherInfo->ownerUid && otherInfo->frameContainsPoint(x, y)) {
2319 if (DEBUG_TOUCH_OCCLUSION) {
2320 info.debugInfo.push_back(
2321 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2322 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002323 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2324 // we perform the checks below to see if the touch can be propagated or not based on the
2325 // window's touch occlusion mode
2326 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2327 info.hasBlockingOcclusion = true;
2328 info.obscuringUid = otherInfo->ownerUid;
2329 info.obscuringPackage = otherInfo->packageName;
2330 break;
2331 }
2332 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2333 uint32_t uid = otherInfo->ownerUid;
2334 float opacity =
2335 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2336 // Given windows A and B:
2337 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2338 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2339 opacityByUid[uid] = opacity;
2340 if (opacity > info.obscuringOpacity) {
2341 info.obscuringOpacity = opacity;
2342 info.obscuringUid = uid;
2343 info.obscuringPackage = otherInfo->packageName;
2344 }
2345 }
2346 }
2347 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002348 if (DEBUG_TOUCH_OCCLUSION) {
2349 info.debugInfo.push_back(
2350 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2351 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002352 return info;
2353}
2354
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002355std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2356 bool isTouchedWindow) const {
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002357 return StringPrintf(INDENT2 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32
2358 ", mode=%s, alpha=%.2f, "
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002359 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2360 "], touchableRegion=%s, window={%s}, applicationInfo=%s, "
2361 "flags={%s}, inputFeatures={%s}, hasToken=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002362 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002363 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002364 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002365 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2366 info->frameTop, info->frameRight, info->frameBottom,
2367 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002368 info->applicationInfo.name.c_str(), info->flags.string().c_str(),
2369 info->inputFeatures.string().c_str(), toString(info->token != nullptr));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002370}
2371
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002372bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2373 if (occlusionInfo.hasBlockingOcclusion) {
2374 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2375 occlusionInfo.obscuringUid);
2376 return false;
2377 }
2378 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2379 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2380 "%.2f, maximum allowed = %.2f)",
2381 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2382 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2383 return false;
2384 }
2385 return true;
2386}
2387
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002388bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2389 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002390 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002391 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002392 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002393 if (windowHandle == otherHandle) {
2394 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002395 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002396 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002397 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002398 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002399 return true;
2400 }
2401 }
2402 return false;
2403}
2404
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002405bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2406 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002407 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002408 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002409 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002410 if (windowHandle == otherHandle) {
2411 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002412 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002413 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002414 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002415 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002416 return true;
2417 }
2418 }
2419 return false;
2420}
2421
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002422std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002423 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002424 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002425 if (applicationHandle != nullptr) {
2426 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002427 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002428 } else {
2429 return applicationHandle->getName();
2430 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002431 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002432 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002433 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002434 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002435 }
2436}
2437
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002438void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002439 if (eventEntry.type == EventEntry::Type::FOCUS ||
2440 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED) {
2441 // Focus or pointer capture changed events are passed to apps, but do not represent user
2442 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002443 return;
2444 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002445 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002446 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002447 if (focusedWindowHandle != nullptr) {
2448 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002449 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002450#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002451 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002452#endif
2453 return;
2454 }
2455 }
2456
2457 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002458 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002459 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002460 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2461 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002462 return;
2463 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002464
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002465 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002466 eventType = USER_ACTIVITY_EVENT_TOUCH;
2467 }
2468 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002469 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002470 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002471 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2472 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002473 return;
2474 }
2475 eventType = USER_ACTIVITY_EVENT_BUTTON;
2476 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002477 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002478 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002479 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002480 case EventEntry::Type::DEVICE_RESET:
2481 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002482 LOG_ALWAYS_FATAL("%s events are not user activity",
2483 EventEntry::typeToString(eventEntry.type));
2484 break;
2485 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002486 }
2487
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002488 std::unique_ptr<CommandEntry> commandEntry =
2489 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002490 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002491 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002492 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002493}
2494
2495void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002496 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002497 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002498 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002499 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002500 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002501 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002502 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002503 ATRACE_NAME(message.c_str());
2504 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002505#if DEBUG_DISPATCH_CYCLE
2506 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002507 "globalScaleFactor=%f, pointerIds=0x%x %s",
2508 connection->getInputChannelName().c_str(), inputTarget.flags,
2509 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2510 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002511#endif
2512
2513 // Skip this event if the connection status is not normal.
2514 // We don't want to enqueue additional outbound events if the connection is broken.
2515 if (connection->status != Connection::STATUS_NORMAL) {
2516#if DEBUG_DISPATCH_CYCLE
2517 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002518 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002519#endif
2520 return;
2521 }
2522
2523 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002524 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2525 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2526 "Entry type %s should not have FLAG_SPLIT",
2527 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002528
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002529 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002530 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002531 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002532 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002533 if (!splitMotionEntry) {
2534 return; // split event was dropped
2535 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002536 if (DEBUG_FOCUS) {
2537 ALOGD("channel '%s' ~ Split motion event.",
2538 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002539 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002540 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002541 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2542 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002543 return;
2544 }
2545 }
2546
2547 // Not splitting. Enqueue dispatch entries for the event as is.
2548 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2549}
2550
2551void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002552 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002553 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002554 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002555 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002556 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002557 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002558 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002559 ATRACE_NAME(message.c_str());
2560 }
2561
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002562 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002563
2564 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002565 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002566 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002567 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002568 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002569 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002570 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002571 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002572 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002573 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002574 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002575 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002576 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002577
2578 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002579 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002580 startDispatchCycleLocked(currentTime, connection);
2581 }
2582}
2583
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002584void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002585 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002586 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002587 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002588 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002589 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2590 connection->getInputChannelName().c_str(),
2591 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002592 ATRACE_NAME(message.c_str());
2593 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002594 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002595 if (!(inputTargetFlags & dispatchMode)) {
2596 return;
2597 }
2598 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2599
2600 // This is a new event.
2601 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002602 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002603 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002604
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002605 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2606 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002607 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002608 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002609 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002610 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002611 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002612 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002613 dispatchEntry->resolvedAction = keyEntry.action;
2614 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002615
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002616 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2617 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002618#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002619 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2620 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002621#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002622 return; // skip the inconsistent event
2623 }
2624 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002625 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002626
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002627 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002628 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002629 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2630 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2631 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2632 static_cast<int32_t>(IdGenerator::Source::OTHER);
2633 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002634 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2635 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2636 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2637 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2638 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2639 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2640 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2641 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2642 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2643 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2644 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002645 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002646 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002647 }
2648 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002649 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2650 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002651#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002652 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2653 "event",
2654 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002655#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002656 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2657 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002658
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002659 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002660 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2661 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2662 }
2663 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2664 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2665 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002666
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002667 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2668 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002669#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002670 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2671 "event",
2672 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002673#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002674 return; // skip the inconsistent event
2675 }
2676
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002677 dispatchEntry->resolvedEventId =
2678 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2679 ? mIdGenerator.nextId()
2680 : motionEntry.id;
2681 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2682 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2683 ") to MotionEvent(id=0x%" PRIx32 ").",
2684 motionEntry.id, dispatchEntry->resolvedEventId);
2685 ATRACE_NAME(message.c_str());
2686 }
2687
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002688 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002689 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002690
2691 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002692 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002693 case EventEntry::Type::FOCUS:
2694 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002695 break;
2696 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002697 case EventEntry::Type::CONFIGURATION_CHANGED:
2698 case EventEntry::Type::DEVICE_RESET: {
2699 LOG_ALWAYS_FATAL("%s events should not go to apps",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002700 EventEntry::typeToString(newEntry.type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002701 break;
2702 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002703 }
2704
2705 // Remember that we are waiting for this dispatch to complete.
2706 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002707 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002708 }
2709
2710 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002711 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002712 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002713}
2714
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002715/**
2716 * This function is purely for debugging. It helps us understand where the user interaction
2717 * was taking place. For example, if user is touching launcher, we will see a log that user
2718 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2719 * We will see both launcher and wallpaper in that list.
2720 * Once the interaction with a particular set of connections starts, no new logs will be printed
2721 * until the set of interacted connections changes.
2722 *
2723 * The following items are skipped, to reduce the logspam:
2724 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2725 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2726 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2727 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2728 * Both of those ACTION_UP events would not be logged
2729 * Monitors (both gesture and global): any gesture monitors or global monitors receiving events
2730 * will not be logged. This is omitted to reduce the amount of data printed.
2731 * If you see <none>, it's likely that one of the gesture monitors pilfered the event, and therefore
2732 * gesture monitor is the only connection receiving the remainder of the gesture.
2733 */
2734void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2735 const std::vector<InputTarget>& targets) {
2736 // Skip ACTION_UP events, and all events other than keys and motions
2737 if (entry.type == EventEntry::Type::KEY) {
2738 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2739 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2740 return;
2741 }
2742 } else if (entry.type == EventEntry::Type::MOTION) {
2743 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2744 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2745 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2746 return;
2747 }
2748 } else {
2749 return; // Not a key or a motion
2750 }
2751
2752 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2753 std::vector<sp<Connection>> newConnections;
2754 for (const InputTarget& target : targets) {
2755 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2756 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2757 continue; // Skip windows that receive ACTION_OUTSIDE
2758 }
2759
2760 sp<IBinder> token = target.inputChannel->getConnectionToken();
2761 sp<Connection> connection = getConnectionLocked(token);
2762 if (connection == nullptr || connection->monitor) {
2763 continue; // We only need to keep track of the non-monitor connections.
2764 }
2765 newConnectionTokens.insert(std::move(token));
2766 newConnections.emplace_back(connection);
2767 }
2768 if (newConnectionTokens == mInteractionConnectionTokens) {
2769 return; // no change
2770 }
2771 mInteractionConnectionTokens = newConnectionTokens;
2772
2773 std::string windowList;
2774 for (const sp<Connection>& connection : newConnections) {
2775 windowList += connection->getWindowName() + ", ";
2776 }
2777 std::string message = "Interaction with windows: " + windowList;
2778 if (windowList.empty()) {
2779 message += "<none>";
2780 }
2781 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2782}
2783
chaviwfd6d3512019-03-25 13:23:49 -07002784void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002785 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002786 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002787 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2788 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002789 return;
2790 }
2791
Vishnu Nairad321cd2020-08-20 16:40:21 -07002792 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
2793 if (focusedToken == token) {
2794 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002795 return;
2796 }
2797
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002798 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2799 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002800 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002801 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002802}
2803
2804void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002805 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002806 if (ATRACE_ENABLED()) {
2807 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002808 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002809 ATRACE_NAME(message.c_str());
2810 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002811#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002812 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002813#endif
2814
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002815 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2816 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002817 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002818 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002819 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002820 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002821
2822 // Publish the event.
2823 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002824 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
2825 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002826 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002827 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2828 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002829
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002830 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002831 status = connection->inputPublisher
2832 .publishKeyEvent(dispatchEntry->seq,
2833 dispatchEntry->resolvedEventId, keyEntry.deviceId,
2834 keyEntry.source, keyEntry.displayId,
2835 std::move(hmac), dispatchEntry->resolvedAction,
2836 dispatchEntry->resolvedFlags, keyEntry.keyCode,
2837 keyEntry.scanCode, keyEntry.metaState,
2838 keyEntry.repeatCount, keyEntry.downTime,
2839 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002840 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002841 }
2842
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002843 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002844 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002845
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002846 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002847 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002848
chaviw82357092020-01-28 13:13:06 -08002849 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002850 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002851 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2852 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002853 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002854 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
2855 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002856 // Don't apply window scale here since we don't want scale to affect raw
2857 // coordinates. The scale will be sent back to the client and applied
2858 // later when requesting relative coordinates.
2859 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2860 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002861 }
2862 usingCoords = scaledCoords;
2863 }
2864 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002865 // We don't want the dispatch target to know.
2866 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002867 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002868 scaledCoords[i].clear();
2869 }
2870 usingCoords = scaledCoords;
2871 }
2872 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002873
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002874 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002875
2876 // Publish the motion event.
2877 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002878 .publishMotionEvent(dispatchEntry->seq,
2879 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002880 motionEntry.deviceId, motionEntry.source,
2881 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002882 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002883 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002884 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002885 motionEntry.edgeFlags, motionEntry.metaState,
2886 motionEntry.buttonState,
2887 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07002888 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002889 motionEntry.xPrecision, motionEntry.yPrecision,
2890 motionEntry.xCursorPosition,
2891 motionEntry.yCursorPosition,
2892 motionEntry.downTime, motionEntry.eventTime,
2893 motionEntry.pointerCount,
2894 motionEntry.pointerProperties, usingCoords);
2895 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002896 break;
2897 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002898
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002899 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002900 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002901 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002902 focusEntry.id,
2903 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002904 mInTouchMode);
2905 break;
2906 }
2907
Prabir Pradhan99987712020-11-10 18:43:05 -08002908 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
2909 const auto& captureEntry =
2910 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
2911 status = connection->inputPublisher
2912 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
2913 captureEntry.pointerCaptureEnabled);
2914 break;
2915 }
2916
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002917 case EventEntry::Type::CONFIGURATION_CHANGED:
2918 case EventEntry::Type::DEVICE_RESET: {
2919 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002920 EventEntry::typeToString(eventEntry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002921 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002922 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002923 }
2924
2925 // Check the result.
2926 if (status) {
2927 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002928 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002929 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002930 "This is unexpected because the wait queue is empty, so the pipe "
2931 "should be empty and we shouldn't have any problems writing an "
2932 "event to it, status=%d",
2933 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002934 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2935 } else {
2936 // Pipe is full and we are waiting for the app to finish process some events
2937 // before sending more events to it.
2938#if DEBUG_DISPATCH_CYCLE
2939 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002940 "waiting for the application to catch up",
2941 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002942#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08002943 }
2944 } else {
2945 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002946 "status=%d",
2947 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002948 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2949 }
2950 return;
2951 }
2952
2953 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002954 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2955 connection->outboundQueue.end(),
2956 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002957 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002958 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002959 if (connection->responsive) {
2960 mAnrTracker.insert(dispatchEntry->timeoutTime,
2961 connection->inputChannel->getConnectionToken());
2962 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002963 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002964 }
2965}
2966
chaviw09c8d2d2020-08-24 15:48:26 -07002967std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
2968 size_t size;
2969 switch (event.type) {
2970 case VerifiedInputEvent::Type::KEY: {
2971 size = sizeof(VerifiedKeyEvent);
2972 break;
2973 }
2974 case VerifiedInputEvent::Type::MOTION: {
2975 size = sizeof(VerifiedMotionEvent);
2976 break;
2977 }
2978 }
2979 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
2980 return mHmacKeyManager.sign(start, size);
2981}
2982
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002983const std::array<uint8_t, 32> InputDispatcher::getSignature(
2984 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
2985 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
2986 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
2987 // Only sign events up and down events as the purely move events
2988 // are tied to their up/down counterparts so signing would be redundant.
2989 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
2990 verifiedEvent.actionMasked = actionMasked;
2991 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07002992 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002993 }
2994 return INVALID_HMAC;
2995}
2996
2997const std::array<uint8_t, 32> InputDispatcher::getSignature(
2998 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
2999 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3000 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3001 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003002 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003003}
3004
Michael Wrightd02c5b62014-02-10 15:10:22 -08003005void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003006 const sp<Connection>& connection, uint32_t seq,
3007 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003008#if DEBUG_DISPATCH_CYCLE
3009 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003010 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003011#endif
3012
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003013 if (connection->status == Connection::STATUS_BROKEN ||
3014 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003015 return;
3016 }
3017
3018 // Notify other system components and prepare to start the next dispatch cycle.
3019 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
3020}
3021
3022void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003023 const sp<Connection>& connection,
3024 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003025#if DEBUG_DISPATCH_CYCLE
3026 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003027 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003028#endif
3029
3030 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003031 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003032 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003033 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003034 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003035
3036 // The connection appears to be unrecoverably broken.
3037 // Ignore already broken or zombie connections.
3038 if (connection->status == Connection::STATUS_NORMAL) {
3039 connection->status = Connection::STATUS_BROKEN;
3040
3041 if (notify) {
3042 // Notify other system components.
3043 onDispatchCycleBrokenLocked(currentTime, connection);
3044 }
3045 }
3046}
3047
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003048void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3049 while (!queue.empty()) {
3050 DispatchEntry* dispatchEntry = queue.front();
3051 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003052 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003053 }
3054}
3055
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003056void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003057 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003058 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003059 }
3060 delete dispatchEntry;
3061}
3062
3063int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
3064 InputDispatcher* d = static_cast<InputDispatcher*>(data);
3065
3066 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003067 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003068
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003069 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003070 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003071 "fd=%d, events=0x%x",
3072 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003073 return 0; // remove the callback
3074 }
3075
3076 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003077 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003078 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3079 if (!(events & ALOOPER_EVENT_INPUT)) {
3080 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003081 "events=0x%x",
3082 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003083 return 1;
3084 }
3085
3086 nsecs_t currentTime = now();
3087 bool gotOne = false;
3088 status_t status;
3089 for (;;) {
3090 uint32_t seq;
3091 bool handled;
3092 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
3093 if (status) {
3094 break;
3095 }
3096 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
3097 gotOne = true;
3098 }
3099 if (gotOne) {
3100 d->runCommandsLockedInterruptible();
3101 if (status == WOULD_BLOCK) {
3102 return 1;
3103 }
3104 }
3105
3106 notify = status != DEAD_OBJECT || !connection->monitor;
3107 if (notify) {
3108 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003109 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003110 }
3111 } else {
3112 // Monitor channels are never explicitly unregistered.
3113 // We do it automatically when the remote endpoint is closed so don't warn
3114 // about them.
arthurhungd352cb32020-04-28 17:09:28 +08003115 const bool stillHaveWindowHandle =
3116 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3117 nullptr;
3118 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003119 if (notify) {
3120 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003121 "events=0x%x",
3122 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003123 }
3124 }
3125
Garfield Tan15601662020-09-22 15:32:38 -07003126 // Remove the channel.
3127 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003128 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003129 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003130}
3131
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003132void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003133 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003134 for (const auto& pair : mConnectionsByFd) {
3135 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003136 }
3137}
3138
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003139void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003140 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003141 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3142 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3143}
3144
3145void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3146 const CancelationOptions& options,
3147 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3148 for (const auto& it : monitorsByDisplay) {
3149 const std::vector<Monitor>& monitors = it.second;
3150 for (const Monitor& monitor : monitors) {
3151 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003152 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003153 }
3154}
3155
Michael Wrightd02c5b62014-02-10 15:10:22 -08003156void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003157 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003158 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003159 if (connection == nullptr) {
3160 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003161 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003162
3163 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003164}
3165
3166void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3167 const sp<Connection>& connection, const CancelationOptions& options) {
3168 if (connection->status == Connection::STATUS_BROKEN) {
3169 return;
3170 }
3171
3172 nsecs_t currentTime = now();
3173
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003174 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003175 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003176
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003177 if (cancelationEvents.empty()) {
3178 return;
3179 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003180#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003181 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3182 "with reality: %s, mode=%d.",
3183 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3184 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003185#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003186
3187 InputTarget target;
3188 sp<InputWindowHandle> windowHandle =
3189 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3190 if (windowHandle != nullptr) {
3191 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003192 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003193 target.globalScaleFactor = windowInfo->globalScaleFactor;
3194 }
3195 target.inputChannel = connection->inputChannel;
3196 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3197
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003198 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003199 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003200 switch (cancelationEventEntry->type) {
3201 case EventEntry::Type::KEY: {
3202 logOutboundKeyDetails("cancel - ",
3203 static_cast<const KeyEntry&>(*cancelationEventEntry));
3204 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003205 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003206 case EventEntry::Type::MOTION: {
3207 logOutboundMotionDetails("cancel - ",
3208 static_cast<const MotionEntry&>(*cancelationEventEntry));
3209 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003210 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003211 case EventEntry::Type::FOCUS:
3212 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3213 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
3214 EventEntry::typeToString(cancelationEventEntry->type));
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003215 break;
3216 }
3217 case EventEntry::Type::CONFIGURATION_CHANGED:
3218 case EventEntry::Type::DEVICE_RESET: {
3219 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3220 EventEntry::typeToString(cancelationEventEntry->type));
3221 break;
3222 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003223 }
3224
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003225 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3226 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003227 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003228
3229 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003230}
3231
Svet Ganov5d3bc372020-01-26 23:11:07 -08003232void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3233 const sp<Connection>& connection) {
3234 if (connection->status == Connection::STATUS_BROKEN) {
3235 return;
3236 }
3237
3238 nsecs_t currentTime = now();
3239
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003240 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003241 connection->inputState.synthesizePointerDownEvents(currentTime);
3242
3243 if (downEvents.empty()) {
3244 return;
3245 }
3246
3247#if DEBUG_OUTBOUND_EVENT_DETAILS
3248 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3249 connection->getInputChannelName().c_str(), downEvents.size());
3250#endif
3251
3252 InputTarget target;
3253 sp<InputWindowHandle> windowHandle =
3254 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3255 if (windowHandle != nullptr) {
3256 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003257 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003258 target.globalScaleFactor = windowInfo->globalScaleFactor;
3259 }
3260 target.inputChannel = connection->inputChannel;
3261 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3262
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003263 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003264 switch (downEventEntry->type) {
3265 case EventEntry::Type::MOTION: {
3266 logOutboundMotionDetails("down - ",
3267 static_cast<const MotionEntry&>(*downEventEntry));
3268 break;
3269 }
3270
3271 case EventEntry::Type::KEY:
3272 case EventEntry::Type::FOCUS:
3273 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003274 case EventEntry::Type::DEVICE_RESET:
3275 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003276 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3277 EventEntry::typeToString(downEventEntry->type));
3278 break;
3279 }
3280 }
3281
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003282 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3283 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003284 }
3285
3286 startDispatchCycleLocked(currentTime, connection);
3287}
3288
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003289std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3290 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003291 ALOG_ASSERT(pointerIds.value != 0);
3292
3293 uint32_t splitPointerIndexMap[MAX_POINTERS];
3294 PointerProperties splitPointerProperties[MAX_POINTERS];
3295 PointerCoords splitPointerCoords[MAX_POINTERS];
3296
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003297 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003298 uint32_t splitPointerCount = 0;
3299
3300 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003301 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003302 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003303 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003304 uint32_t pointerId = uint32_t(pointerProperties.id);
3305 if (pointerIds.hasBit(pointerId)) {
3306 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3307 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3308 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003309 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003310 splitPointerCount += 1;
3311 }
3312 }
3313
3314 if (splitPointerCount != pointerIds.count()) {
3315 // This is bad. We are missing some of the pointers that we expected to deliver.
3316 // Most likely this indicates that we received an ACTION_MOVE events that has
3317 // different pointer ids than we expected based on the previous ACTION_DOWN
3318 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3319 // in this way.
3320 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003321 "we expected there to be %d pointers. This probably means we received "
3322 "a broken sequence of pointer ids from the input device.",
3323 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003324 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003325 }
3326
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003327 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003328 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003329 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3330 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003331 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3332 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003333 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003334 uint32_t pointerId = uint32_t(pointerProperties.id);
3335 if (pointerIds.hasBit(pointerId)) {
3336 if (pointerIds.count() == 1) {
3337 // The first/last pointer went down/up.
3338 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003339 ? AMOTION_EVENT_ACTION_DOWN
3340 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003341 } else {
3342 // A secondary pointer went down/up.
3343 uint32_t splitPointerIndex = 0;
3344 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3345 splitPointerIndex += 1;
3346 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003347 action = maskedAction |
3348 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003349 }
3350 } else {
3351 // An unrelated pointer changed.
3352 action = AMOTION_EVENT_ACTION_MOVE;
3353 }
3354 }
3355
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003356 int32_t newId = mIdGenerator.nextId();
3357 if (ATRACE_ENABLED()) {
3358 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3359 ") to MotionEvent(id=0x%" PRIx32 ").",
3360 originalMotionEntry.id, newId);
3361 ATRACE_NAME(message.c_str());
3362 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003363 std::unique_ptr<MotionEntry> splitMotionEntry =
3364 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3365 originalMotionEntry.deviceId, originalMotionEntry.source,
3366 originalMotionEntry.displayId,
3367 originalMotionEntry.policyFlags, action,
3368 originalMotionEntry.actionButton,
3369 originalMotionEntry.flags, originalMotionEntry.metaState,
3370 originalMotionEntry.buttonState,
3371 originalMotionEntry.classification,
3372 originalMotionEntry.edgeFlags,
3373 originalMotionEntry.xPrecision,
3374 originalMotionEntry.yPrecision,
3375 originalMotionEntry.xCursorPosition,
3376 originalMotionEntry.yCursorPosition,
3377 originalMotionEntry.downTime, splitPointerCount,
3378 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003379
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003380 if (originalMotionEntry.injectionState) {
3381 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003382 splitMotionEntry->injectionState->refCount += 1;
3383 }
3384
3385 return splitMotionEntry;
3386}
3387
3388void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3389#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003390 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003391#endif
3392
3393 bool needWake;
3394 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003395 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003396
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003397 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3398 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3399 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003400 } // release lock
3401
3402 if (needWake) {
3403 mLooper->wake();
3404 }
3405}
3406
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003407/**
3408 * If one of the meta shortcuts is detected, process them here:
3409 * Meta + Backspace -> generate BACK
3410 * Meta + Enter -> generate HOME
3411 * This will potentially overwrite keyCode and metaState.
3412 */
3413void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003414 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003415 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3416 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3417 if (keyCode == AKEYCODE_DEL) {
3418 newKeyCode = AKEYCODE_BACK;
3419 } else if (keyCode == AKEYCODE_ENTER) {
3420 newKeyCode = AKEYCODE_HOME;
3421 }
3422 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003423 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003424 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003425 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003426 keyCode = newKeyCode;
3427 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3428 }
3429 } else if (action == AKEY_EVENT_ACTION_UP) {
3430 // In order to maintain a consistent stream of up and down events, check to see if the key
3431 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3432 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003433 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003434 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003435 auto replacementIt = mReplacedKeys.find(replacement);
3436 if (replacementIt != mReplacedKeys.end()) {
3437 keyCode = replacementIt->second;
3438 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003439 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3440 }
3441 }
3442}
3443
Michael Wrightd02c5b62014-02-10 15:10:22 -08003444void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3445#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003446 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3447 "policyFlags=0x%x, action=0x%x, "
3448 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3449 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3450 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3451 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003452#endif
3453 if (!validateKeyEvent(args->action)) {
3454 return;
3455 }
3456
3457 uint32_t policyFlags = args->policyFlags;
3458 int32_t flags = args->flags;
3459 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003460 // InputDispatcher tracks and generates key repeats on behalf of
3461 // whatever notifies it, so repeatCount should always be set to 0
3462 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003463 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3464 policyFlags |= POLICY_FLAG_VIRTUAL;
3465 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3466 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003467 if (policyFlags & POLICY_FLAG_FUNCTION) {
3468 metaState |= AMETA_FUNCTION_ON;
3469 }
3470
3471 policyFlags |= POLICY_FLAG_TRUSTED;
3472
Michael Wright78f24442014-08-06 15:55:28 -07003473 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003474 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003475
Michael Wrightd02c5b62014-02-10 15:10:22 -08003476 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003477 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003478 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3479 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003480
Michael Wright2b3c3302018-03-02 17:19:13 +00003481 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003482 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003483 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3484 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003485 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003486 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003487
Michael Wrightd02c5b62014-02-10 15:10:22 -08003488 bool needWake;
3489 { // acquire lock
3490 mLock.lock();
3491
3492 if (shouldSendKeyToInputFilterLocked(args)) {
3493 mLock.unlock();
3494
3495 policyFlags |= POLICY_FLAG_FILTERED;
3496 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3497 return; // event was consumed by the filter
3498 }
3499
3500 mLock.lock();
3501 }
3502
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003503 std::unique_ptr<KeyEntry> newEntry =
3504 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3505 args->displayId, policyFlags, args->action, flags,
3506 keyCode, args->scanCode, metaState, repeatCount,
3507 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003508
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003509 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003510 mLock.unlock();
3511 } // release lock
3512
3513 if (needWake) {
3514 mLooper->wake();
3515 }
3516}
3517
3518bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3519 return mInputFilterEnabled;
3520}
3521
3522void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3523#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003524 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3525 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003526 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3527 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003528 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003529 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3530 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3531 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3532 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003533 for (uint32_t i = 0; i < args->pointerCount; i++) {
3534 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003535 "x=%f, y=%f, pressure=%f, size=%f, "
3536 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3537 "orientation=%f",
3538 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3539 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3540 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3541 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3542 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3543 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3544 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3545 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3546 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3547 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003548 }
3549#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003550 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3551 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003552 return;
3553 }
3554
3555 uint32_t policyFlags = args->policyFlags;
3556 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003557
3558 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003559 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003560 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3561 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003562 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003563 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003564
3565 bool needWake;
3566 { // acquire lock
3567 mLock.lock();
3568
3569 if (shouldSendMotionToInputFilterLocked(args)) {
3570 mLock.unlock();
3571
3572 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003573 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003574 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3575 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003576 args->metaState, args->buttonState, args->classification, transform,
3577 args->xPrecision, args->yPrecision, args->xCursorPosition,
3578 args->yCursorPosition, args->downTime, args->eventTime,
3579 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003580
3581 policyFlags |= POLICY_FLAG_FILTERED;
3582 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3583 return; // event was consumed by the filter
3584 }
3585
3586 mLock.lock();
3587 }
3588
3589 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003590 std::unique_ptr<MotionEntry> newEntry =
3591 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3592 args->source, args->displayId, policyFlags,
3593 args->action, args->actionButton, args->flags,
3594 args->metaState, args->buttonState,
3595 args->classification, args->edgeFlags,
3596 args->xPrecision, args->yPrecision,
3597 args->xCursorPosition, args->yCursorPosition,
3598 args->downTime, args->pointerCount,
3599 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003600
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003601 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003602 mLock.unlock();
3603 } // release lock
3604
3605 if (needWake) {
3606 mLooper->wake();
3607 }
3608}
3609
3610bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003611 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003612}
3613
3614void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3615#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003616 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003617 "switchMask=0x%08x",
3618 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003619#endif
3620
3621 uint32_t policyFlags = args->policyFlags;
3622 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003623 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003624}
3625
3626void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3627#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003628 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3629 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003630#endif
3631
3632 bool needWake;
3633 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003634 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003635
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003636 std::unique_ptr<DeviceResetEntry> newEntry =
3637 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3638 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003639 } // release lock
3640
3641 if (needWake) {
3642 mLooper->wake();
3643 }
3644}
3645
Prabir Pradhan7e186182020-11-10 13:56:45 -08003646void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3647#if DEBUG_INBOUND_EVENT_DETAILS
3648 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3649 args->enabled ? "true" : "false");
3650#endif
3651
Prabir Pradhan99987712020-11-10 18:43:05 -08003652 bool needWake;
3653 { // acquire lock
3654 std::scoped_lock _l(mLock);
3655 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
3656 args->enabled);
3657 needWake = enqueueInboundEventLocked(std::move(entry));
3658 } // release lock
3659
3660 if (needWake) {
3661 mLooper->wake();
3662 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003663}
3664
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003665InputEventInjectionResult InputDispatcher::injectInputEvent(
3666 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3667 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003668#if DEBUG_INBOUND_EVENT_DETAILS
3669 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003670 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3671 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003672#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003673 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003674
3675 policyFlags |= POLICY_FLAG_INJECTED;
3676 if (hasInjectionPermission(injectorPid, injectorUid)) {
3677 policyFlags |= POLICY_FLAG_TRUSTED;
3678 }
3679
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003680 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003681 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003682 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003683 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3684 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003685 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003686 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003687 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003688
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003689 int32_t flags = incomingKey.getFlags();
3690 int32_t keyCode = incomingKey.getKeyCode();
3691 int32_t metaState = incomingKey.getMetaState();
3692 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003693 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003694 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003695 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003696 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3697 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3698 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003699
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003700 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3701 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003702 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003703
3704 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3705 android::base::Timer t;
3706 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3707 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3708 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3709 std::to_string(t.duration().count()).c_str());
3710 }
3711 }
3712
3713 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003714 std::unique_ptr<KeyEntry> injectedEntry =
3715 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3716 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3717 incomingKey.getDisplayId(), policyFlags, action,
3718 flags, keyCode, incomingKey.getScanCode(), metaState,
3719 incomingKey.getRepeatCount(),
3720 incomingKey.getDownTime());
3721 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003722 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003723 }
3724
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003725 case AINPUT_EVENT_TYPE_MOTION: {
3726 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3727 int32_t action = motionEvent->getAction();
3728 size_t pointerCount = motionEvent->getPointerCount();
3729 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3730 int32_t actionButton = motionEvent->getActionButton();
3731 int32_t displayId = motionEvent->getDisplayId();
3732 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003733 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003734 }
3735
3736 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3737 nsecs_t eventTime = motionEvent->getEventTime();
3738 android::base::Timer t;
3739 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3740 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3741 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3742 std::to_string(t.duration().count()).c_str());
3743 }
3744 }
3745
3746 mLock.lock();
3747 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3748 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003749 std::unique_ptr<MotionEntry> injectedEntry =
3750 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3751 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3752 motionEvent->getDisplayId(), policyFlags, action,
3753 actionButton, motionEvent->getFlags(),
3754 motionEvent->getMetaState(),
3755 motionEvent->getButtonState(),
3756 motionEvent->getClassification(),
3757 motionEvent->getEdgeFlags(),
3758 motionEvent->getXPrecision(),
3759 motionEvent->getYPrecision(),
3760 motionEvent->getRawXCursorPosition(),
3761 motionEvent->getRawYCursorPosition(),
3762 motionEvent->getDownTime(),
3763 uint32_t(pointerCount), pointerProperties,
3764 samplePointerCoords, motionEvent->getXOffset(),
3765 motionEvent->getYOffset());
3766 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003767 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3768 sampleEventTimes += 1;
3769 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003770 std::unique_ptr<MotionEntry> nextInjectedEntry =
3771 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3772 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3773 motionEvent->getDisplayId(), policyFlags,
3774 action, actionButton, motionEvent->getFlags(),
3775 motionEvent->getMetaState(),
3776 motionEvent->getButtonState(),
3777 motionEvent->getClassification(),
3778 motionEvent->getEdgeFlags(),
3779 motionEvent->getXPrecision(),
3780 motionEvent->getYPrecision(),
3781 motionEvent->getRawXCursorPosition(),
3782 motionEvent->getRawYCursorPosition(),
3783 motionEvent->getDownTime(),
3784 uint32_t(pointerCount), pointerProperties,
3785 samplePointerCoords,
3786 motionEvent->getXOffset(),
3787 motionEvent->getYOffset());
3788 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003789 }
3790 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003791 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003792
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003793 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003794 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003795 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003796 }
3797
3798 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003799 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003800 injectionState->injectionIsAsync = true;
3801 }
3802
3803 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003804 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003805
3806 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003807 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003808 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003809 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003810 }
3811
3812 mLock.unlock();
3813
3814 if (needWake) {
3815 mLooper->wake();
3816 }
3817
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003818 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003819 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003820 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003821
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003822 if (syncMode == InputEventInjectionSync::NONE) {
3823 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003824 } else {
3825 for (;;) {
3826 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003827 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003828 break;
3829 }
3830
3831 nsecs_t remainingTimeout = endTime - now();
3832 if (remainingTimeout <= 0) {
3833#if DEBUG_INJECTION
3834 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003835 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003836#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003837 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003838 break;
3839 }
3840
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003841 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003842 }
3843
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003844 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3845 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003846 while (injectionState->pendingForegroundDispatches != 0) {
3847#if DEBUG_INJECTION
3848 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003849 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003850#endif
3851 nsecs_t remainingTimeout = endTime - now();
3852 if (remainingTimeout <= 0) {
3853#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003854 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3855 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003856#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003857 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003858 break;
3859 }
3860
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003861 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003862 }
3863 }
3864 }
3865
3866 injectionState->release();
3867 } // release lock
3868
3869#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003870 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003871 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003872#endif
3873
3874 return injectionResult;
3875}
3876
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003877std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05003878 std::array<uint8_t, 32> calculatedHmac;
3879 std::unique_ptr<VerifiedInputEvent> result;
3880 switch (event.getType()) {
3881 case AINPUT_EVENT_TYPE_KEY: {
3882 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
3883 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
3884 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003885 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05003886 break;
3887 }
3888 case AINPUT_EVENT_TYPE_MOTION: {
3889 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
3890 VerifiedMotionEvent verifiedMotionEvent =
3891 verifiedMotionEventFromMotionEvent(motionEvent);
3892 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003893 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05003894 break;
3895 }
3896 default: {
3897 ALOGE("Cannot verify events of type %" PRId32, event.getType());
3898 return nullptr;
3899 }
3900 }
3901 if (calculatedHmac == INVALID_HMAC) {
3902 return nullptr;
3903 }
3904 if (calculatedHmac != event.getHmac()) {
3905 return nullptr;
3906 }
3907 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003908}
3909
Michael Wrightd02c5b62014-02-10 15:10:22 -08003910bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003911 return injectorUid == 0 ||
3912 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003913}
3914
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003915void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003916 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003917 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003918 if (injectionState) {
3919#if DEBUG_INJECTION
3920 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003921 "injectorPid=%d, injectorUid=%d",
3922 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003923#endif
3924
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003925 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003926 // Log the outcome since the injector did not wait for the injection result.
3927 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003928 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003929 ALOGV("Asynchronous input event injection succeeded.");
3930 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003931 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003932 ALOGW("Asynchronous input event injection failed.");
3933 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003934 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003935 ALOGW("Asynchronous input event injection permission denied.");
3936 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003937 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003938 ALOGW("Asynchronous input event injection timed out.");
3939 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003940 case InputEventInjectionResult::PENDING:
3941 ALOGE("Setting result to 'PENDING' for asynchronous injection");
3942 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003943 }
3944 }
3945
3946 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003947 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003948 }
3949}
3950
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003951void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
3952 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003953 if (injectionState) {
3954 injectionState->pendingForegroundDispatches += 1;
3955 }
3956}
3957
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003958void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
3959 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003960 if (injectionState) {
3961 injectionState->pendingForegroundDispatches -= 1;
3962
3963 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003964 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003965 }
3966 }
3967}
3968
Vishnu Nairad321cd2020-08-20 16:40:21 -07003969const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003970 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003971 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
3972 auto it = mWindowHandlesByDisplay.find(displayId);
3973 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08003974}
3975
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003977 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08003978 if (windowHandleToken == nullptr) {
3979 return nullptr;
3980 }
3981
Arthur Hungb92218b2018-08-14 12:00:21 +08003982 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003983 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003984 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003985 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003986 return windowHandle;
3987 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003988 }
3989 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003990 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003991}
3992
Vishnu Nairad321cd2020-08-20 16:40:21 -07003993sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
3994 int displayId) const {
3995 if (windowHandleToken == nullptr) {
3996 return nullptr;
3997 }
3998
3999 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
4000 if (windowHandle->getToken() == windowHandleToken) {
4001 return windowHandle;
4002 }
4003 }
4004 return nullptr;
4005}
4006
4007sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
4008 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4009 return getWindowHandleLocked(focusedToken, displayId);
4010}
4011
Mady Mellor017bcd12020-06-23 19:12:00 +00004012bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
4013 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004014 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00004015 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004016 if (handle->getId() == windowHandle->getId() &&
4017 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004018 if (windowHandle->getInfo()->displayId != it.first) {
4019 ALOGE("Found window %s in display %" PRId32
4020 ", but it should belong to display %" PRId32,
4021 windowHandle->getName().c_str(), it.first,
4022 windowHandle->getInfo()->displayId);
4023 }
4024 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08004025 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004026 }
4027 }
4028 return false;
4029}
4030
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004031bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
4032 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4033 const bool noInputChannel =
4034 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4035 if (connection != nullptr && noInputChannel) {
4036 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4037 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4038 return false;
4039 }
4040
4041 if (connection == nullptr) {
4042 if (!noInputChannel) {
4043 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4044 }
4045 return false;
4046 }
4047 if (!connection->responsive) {
4048 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4049 return false;
4050 }
4051 return true;
4052}
4053
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004054std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4055 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07004056 size_t count = mInputChannelsByToken.count(token);
4057 if (count == 0) {
4058 return nullptr;
4059 }
4060 return mInputChannelsByToken.at(token);
4061}
4062
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004063void InputDispatcher::updateWindowHandlesForDisplayLocked(
4064 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
4065 if (inputWindowHandles.empty()) {
4066 // Remove all handles on a display if there are no windows left.
4067 mWindowHandlesByDisplay.erase(displayId);
4068 return;
4069 }
4070
4071 // Since we compare the pointer of input window handles across window updates, we need
4072 // to make sure the handle object for the same window stays unchanged across updates.
4073 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07004074 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004075 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004076 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004077 }
4078
4079 std::vector<sp<InputWindowHandle>> newHandles;
4080 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
4081 if (!handle->updateInfo()) {
4082 // handle no longer valid
4083 continue;
4084 }
4085
4086 const InputWindowInfo* info = handle->getInfo();
4087 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4088 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4089 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01004090 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4091 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
4092 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004093 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004094 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004095 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004096 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004097 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004098 }
4099
4100 if (info->displayId != displayId) {
4101 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4102 handle->getName().c_str(), displayId, info->displayId);
4103 continue;
4104 }
4105
Robert Carredd13602020-04-13 17:24:34 -07004106 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4107 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004108 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004109 oldHandle->updateFrom(handle);
4110 newHandles.push_back(oldHandle);
4111 } else {
4112 newHandles.push_back(handle);
4113 }
4114 }
4115
4116 // Insert or replace
4117 mWindowHandlesByDisplay[displayId] = newHandles;
4118}
4119
Arthur Hung72d8dc32020-03-28 00:48:39 +00004120void InputDispatcher::setInputWindows(
4121 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4122 { // acquire lock
4123 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004124 for (const auto& [displayId, handles] : handlesPerDisplay) {
4125 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004126 }
4127 }
4128 // Wake up poll loop since it may need to make new input dispatching choices.
4129 mLooper->wake();
4130}
4131
Arthur Hungb92218b2018-08-14 12:00:21 +08004132/**
4133 * Called from InputManagerService, update window handle list by displayId that can receive input.
4134 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4135 * If set an empty list, remove all handles from the specific display.
4136 * For focused handle, check if need to change and send a cancel event to previous one.
4137 * For removed handle, check if need to send a cancel event if already in touch.
4138 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004139void InputDispatcher::setInputWindowsLocked(
4140 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004141 if (DEBUG_FOCUS) {
4142 std::string windowList;
4143 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4144 windowList += iwh->getName() + " ";
4145 }
4146 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4147 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004148
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004149 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4150 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4151 const bool noInputWindow =
4152 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4153 if (noInputWindow && window->getToken() != nullptr) {
4154 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4155 window->getName().c_str());
4156 window->releaseChannel();
4157 }
4158 }
4159
Arthur Hung72d8dc32020-03-28 00:48:39 +00004160 // Copy old handles for release if they are no longer present.
4161 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004162
Arthur Hung72d8dc32020-03-28 00:48:39 +00004163 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004164
Vishnu Nair958da932020-08-21 17:12:37 -07004165 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4166 if (mLastHoverWindowHandle &&
4167 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4168 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004169 mLastHoverWindowHandle = nullptr;
4170 }
4171
Vishnu Nair958da932020-08-21 17:12:37 -07004172 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4173 if (focusedToken) {
4174 FocusResult result = checkTokenFocusableLocked(focusedToken, displayId);
4175 if (result != FocusResult::OK) {
4176 onFocusChangedLocked(focusedToken, nullptr, displayId, typeToString(result));
4177 }
4178 }
4179
4180 std::optional<FocusRequest> focusRequest =
4181 getOptionalValueByKey(mPendingFocusRequests, displayId);
4182 if (focusRequest) {
4183 // If the window from the pending request is now visible, provide it focus.
4184 FocusResult result = handleFocusRequestLocked(*focusRequest);
4185 if (result != FocusResult::NOT_VISIBLE) {
4186 // Drop the request if we were able to change the focus or we cannot change
4187 // it for another reason.
4188 mPendingFocusRequests.erase(displayId);
4189 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004190 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004191
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004192 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4193 mTouchStatesByDisplay.find(displayId);
4194 if (stateIt != mTouchStatesByDisplay.end()) {
4195 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004196 for (size_t i = 0; i < state.windows.size();) {
4197 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004198 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004199 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004200 ALOGD("Touched window was removed: %s in display %" PRId32,
4201 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004202 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004203 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004204 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4205 if (touchedInputChannel != nullptr) {
4206 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4207 "touched window was removed");
4208 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004209 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004210 state.windows.erase(state.windows.begin() + i);
4211 } else {
4212 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004213 }
4214 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004215 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004216
Arthur Hung72d8dc32020-03-28 00:48:39 +00004217 // Release information for windows that are no longer present.
4218 // This ensures that unused input channels are released promptly.
4219 // Otherwise, they might stick around until the window handle is destroyed
4220 // which might not happen until the next GC.
4221 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004222 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004223 if (DEBUG_FOCUS) {
4224 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004225 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004226 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004227 // To avoid making too many calls into the compat framework, only
4228 // check for window flags when windows are going away.
4229 // TODO(b/157929241) : delete this. This is only needed temporarily
4230 // in order to gather some data about the flag usage
4231 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4232 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4233 oldWindowHandle->getName().c_str());
4234 if (mCompatService != nullptr) {
4235 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4236 oldWindowHandle->getInfo()->ownerUid);
4237 }
4238 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004239 }
chaviw291d88a2019-02-14 10:33:58 -08004240 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004241}
4242
4243void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004244 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004245 if (DEBUG_FOCUS) {
4246 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4247 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4248 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004249 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004250 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004251
Chris Yea209fde2020-07-22 13:54:51 -07004252 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004253 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004254
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004255 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4256 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004257 }
4258
Chris Yea209fde2020-07-22 13:54:51 -07004259 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004260 if (inputApplicationHandle != nullptr) {
4261 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4262 } else {
4263 mFocusedApplicationHandlesByDisplay.erase(displayId);
4264 }
4265
4266 // No matter what the old focused application was, stop waiting on it because it is
4267 // no longer focused.
4268 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004269 } // release lock
4270
4271 // Wake up poll loop since it may need to make new input dispatching choices.
4272 mLooper->wake();
4273}
4274
Tiger Huang721e26f2018-07-24 22:26:19 +08004275/**
4276 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4277 * the display not specified.
4278 *
4279 * We track any unreleased events for each window. If a window loses the ability to receive the
4280 * released event, we will send a cancel event to it. So when the focused display is changed, we
4281 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4282 * display. The display-specified events won't be affected.
4283 */
4284void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004285 if (DEBUG_FOCUS) {
4286 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4287 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004288 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004289 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004290
4291 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004292 sp<IBinder> oldFocusedWindowToken =
4293 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4294 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004295 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004296 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004297 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004298 CancelationOptions
4299 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4300 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004301 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004302 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4303 }
4304 }
4305 mFocusedDisplayId = displayId;
4306
Chris Ye3c2d6f52020-08-09 10:39:48 -07004307 // Find new focused window and validate
Vishnu Nairad321cd2020-08-20 16:40:21 -07004308 sp<IBinder> newFocusedWindowToken =
4309 getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4310 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004311
Vishnu Nairad321cd2020-08-20 16:40:21 -07004312 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004313 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004314 if (!mFocusedWindowTokenByDisplay.empty()) {
4315 ALOGE("But another display has a focused window\n%s",
4316 dumpFocusedWindowsLocked().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004317 }
4318 }
4319 }
4320
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004321 if (DEBUG_FOCUS) {
4322 logDispatchStateLocked();
4323 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004324 } // release lock
4325
4326 // Wake up poll loop since it may need to make new input dispatching choices.
4327 mLooper->wake();
4328}
4329
Michael Wrightd02c5b62014-02-10 15:10:22 -08004330void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004331 if (DEBUG_FOCUS) {
4332 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4333 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004334
4335 bool changed;
4336 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004337 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004338
4339 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4340 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004341 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004342 }
4343
4344 if (mDispatchEnabled && !enabled) {
4345 resetAndDropEverythingLocked("dispatcher is being disabled");
4346 }
4347
4348 mDispatchEnabled = enabled;
4349 mDispatchFrozen = frozen;
4350 changed = true;
4351 } else {
4352 changed = false;
4353 }
4354
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004355 if (DEBUG_FOCUS) {
4356 logDispatchStateLocked();
4357 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004358 } // release lock
4359
4360 if (changed) {
4361 // Wake up poll loop since it may need to make new input dispatching choices.
4362 mLooper->wake();
4363 }
4364}
4365
4366void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004367 if (DEBUG_FOCUS) {
4368 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4369 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004370
4371 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004372 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004373
4374 if (mInputFilterEnabled == enabled) {
4375 return;
4376 }
4377
4378 mInputFilterEnabled = enabled;
4379 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4380 } // release lock
4381
4382 // Wake up poll loop since there might be work to do to drop everything.
4383 mLooper->wake();
4384}
4385
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004386void InputDispatcher::setInTouchMode(bool inTouchMode) {
4387 std::scoped_lock lock(mLock);
4388 mInTouchMode = inTouchMode;
4389}
4390
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004391void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4392 if (opacity < 0 || opacity > 1) {
4393 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4394 return;
4395 }
4396
4397 std::scoped_lock lock(mLock);
4398 mMaximumObscuringOpacityForTouch = opacity;
4399}
4400
4401void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4402 std::scoped_lock lock(mLock);
4403 mBlockUntrustedTouchesMode = mode;
4404}
4405
chaviwfbe5d9c2018-12-26 12:23:37 -08004406bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4407 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004408 if (DEBUG_FOCUS) {
4409 ALOGD("Trivial transfer to same window.");
4410 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004411 return true;
4412 }
4413
Michael Wrightd02c5b62014-02-10 15:10:22 -08004414 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004415 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004416
chaviwfbe5d9c2018-12-26 12:23:37 -08004417 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4418 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004419 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004420 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004421 return false;
4422 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004423 if (DEBUG_FOCUS) {
4424 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4425 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4426 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004427 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004428 if (DEBUG_FOCUS) {
4429 ALOGD("Cannot transfer focus because windows are on different displays.");
4430 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004431 return false;
4432 }
4433
4434 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004435 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4436 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004437 for (size_t i = 0; i < state.windows.size(); i++) {
4438 const TouchedWindow& touchedWindow = state.windows[i];
4439 if (touchedWindow.windowHandle == fromWindowHandle) {
4440 int32_t oldTargetFlags = touchedWindow.targetFlags;
4441 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004442
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004443 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004444
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004445 int32_t newTargetFlags = oldTargetFlags &
4446 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4447 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004448 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004449
Jeff Brownf086ddb2014-02-11 14:28:48 -08004450 found = true;
4451 goto Found;
4452 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004453 }
4454 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004455 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004456
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004457 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004458 if (DEBUG_FOCUS) {
4459 ALOGD("Focus transfer failed because from window did not have focus.");
4460 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004461 return false;
4462 }
4463
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004464 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4465 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004466 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004467 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004468 CancelationOptions
4469 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4470 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004471 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004472 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004473 }
4474
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004475 if (DEBUG_FOCUS) {
4476 logDispatchStateLocked();
4477 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004478 } // release lock
4479
4480 // Wake up poll loop since it may need to make new input dispatching choices.
4481 mLooper->wake();
4482 return true;
4483}
4484
4485void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004486 if (DEBUG_FOCUS) {
4487 ALOGD("Resetting and dropping all events (%s).", reason);
4488 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004489
4490 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4491 synthesizeCancelationEventsForAllConnectionsLocked(options);
4492
4493 resetKeyRepeatLocked();
4494 releasePendingEventLocked();
4495 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004496 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004497
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004498 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004499 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004500 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004501 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004502}
4503
4504void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004505 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004506 dumpDispatchStateLocked(dump);
4507
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004508 std::istringstream stream(dump);
4509 std::string line;
4510
4511 while (std::getline(stream, line, '\n')) {
4512 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004513 }
4514}
4515
Vishnu Nairad321cd2020-08-20 16:40:21 -07004516std::string InputDispatcher::dumpFocusedWindowsLocked() {
4517 if (mFocusedWindowTokenByDisplay.empty()) {
4518 return INDENT "FocusedWindows: <none>\n";
4519 }
4520
4521 std::string dump;
4522 dump += INDENT "FocusedWindows:\n";
4523 for (auto& it : mFocusedWindowTokenByDisplay) {
4524 const int32_t displayId = it.first;
4525 const sp<InputWindowHandle> windowHandle = getFocusedWindowHandleLocked(displayId);
4526 if (windowHandle) {
4527 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
4528 windowHandle->getName().c_str());
4529 } else {
4530 dump += StringPrintf(INDENT2 "displayId=%" PRId32
4531 " has focused token without a window'\n",
4532 displayId);
4533 }
4534 }
4535 return dump;
4536}
4537
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004538std::string InputDispatcher::dumpPendingFocusRequestsLocked() {
4539 if (mPendingFocusRequests.empty()) {
4540 return INDENT "mPendingFocusRequests: <none>\n";
4541 }
4542
4543 std::string dump;
4544 dump += INDENT "mPendingFocusRequests:\n";
4545 for (const auto& [displayId, focusRequest] : mPendingFocusRequests) {
4546 // Rather than printing raw values for focusRequest.token and focusRequest.focusedToken,
4547 // try to resolve them to actual windows.
4548 std::string windowName = getConnectionNameLocked(focusRequest.token);
4549 std::string focusedWindowName = getConnectionNameLocked(focusRequest.focusedToken);
4550 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", token->%s, focusedToken->%s\n",
4551 displayId, windowName.c_str(), focusedWindowName.c_str());
4552 }
4553 return dump;
4554}
4555
Prabir Pradhan99987712020-11-10 18:43:05 -08004556std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4557 std::string dump;
4558
4559 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4560 toString(mFocusedWindowRequestedPointerCapture));
4561
4562 std::string windowName = "None";
4563 if (mWindowTokenWithPointerCapture) {
4564 const sp<InputWindowHandle> captureWindowHandle =
4565 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4566 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4567 : "token has capture without window";
4568 }
4569 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4570
4571 return dump;
4572}
4573
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004574void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004575 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4576 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4577 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004578 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004579
Tiger Huang721e26f2018-07-24 22:26:19 +08004580 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4581 dump += StringPrintf(INDENT "FocusedApplications:\n");
4582 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4583 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004584 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004585 const std::chrono::duration timeout =
4586 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004587 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004588 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004589 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004590 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004591 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004592 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004593 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004594
Vishnu Nairad321cd2020-08-20 16:40:21 -07004595 dump += dumpFocusedWindowsLocked();
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004596 dump += dumpPendingFocusRequestsLocked();
Prabir Pradhan99987712020-11-10 18:43:05 -08004597 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004598
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004599 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004600 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004601 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4602 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004603 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004604 state.displayId, toString(state.down), toString(state.split),
4605 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004606 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004607 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004608 for (size_t i = 0; i < state.windows.size(); i++) {
4609 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004610 dump += StringPrintf(INDENT4
4611 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4612 i, touchedWindow.windowHandle->getName().c_str(),
4613 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004614 }
4615 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004616 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004617 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004618 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004619 dump += INDENT3 "Portal windows:\n";
4620 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004621 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004622 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4623 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004624 }
4625 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004626 }
4627 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004628 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004629 }
4630
Arthur Hungb92218b2018-08-14 12:00:21 +08004631 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004632 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004633 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004634 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004635 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004636 dump += INDENT2 "Windows:\n";
4637 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004638 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004639 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004640
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004641 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004642 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004643 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004644 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004645 "frame=[%d,%d][%d,%d], globalScale=%f, "
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004646 "applicationInfo=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004647 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004648 i, windowInfo->name.c_str(), windowInfo->id,
4649 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004650 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004651 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004652 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004653 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004654 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004655 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004656 windowInfo->frameLeft, windowInfo->frameTop,
4657 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004658 windowInfo->globalScaleFactor,
4659 windowInfo->applicationInfo.name.c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004660 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004661 dump += StringPrintf(", inputFeatures=%s",
4662 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004663 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004664 "ms, trustedOverlay=%s, hasToken=%s, "
4665 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004666 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004667 millis(windowInfo->dispatchingTimeout),
4668 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004669 toString(windowInfo->token != nullptr),
4670 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004671 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004672 }
4673 } else {
4674 dump += INDENT2 "Windows: <none>\n";
4675 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004676 }
4677 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004678 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004679 }
4680
Michael Wright3dd60e22019-03-27 22:06:44 +00004681 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004682 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004683 const std::vector<Monitor>& monitors = it.second;
4684 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4685 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004686 }
4687 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004688 const std::vector<Monitor>& monitors = it.second;
4689 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4690 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004691 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004692 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004693 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004694 }
4695
4696 nsecs_t currentTime = now();
4697
4698 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004699 if (!mRecentQueue.empty()) {
4700 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004701 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004702 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004703 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004704 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004705 }
4706 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004707 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004708 }
4709
4710 // Dump event currently being dispatched.
4711 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004712 dump += INDENT "PendingEvent:\n";
4713 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004714 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004715 dump += StringPrintf(", age=%" PRId64 "ms\n",
4716 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004717 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004718 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004719 }
4720
4721 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004722 if (!mInboundQueue.empty()) {
4723 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004724 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004725 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004726 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004727 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004728 }
4729 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004730 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004731 }
4732
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004733 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004734 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004735 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4736 const KeyReplacement& replacement = pair.first;
4737 int32_t newKeyCode = pair.second;
4738 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004739 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004740 }
4741 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004742 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004743 }
4744
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004745 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004746 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004747 for (const auto& pair : mConnectionsByFd) {
4748 const sp<Connection>& connection = pair.second;
4749 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004750 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004751 pair.first, connection->getInputChannelName().c_str(),
4752 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004753 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004754
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004755 if (!connection->outboundQueue.empty()) {
4756 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4757 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004758 dump += dumpQueue(connection->outboundQueue, currentTime);
4759
Michael Wrightd02c5b62014-02-10 15:10:22 -08004760 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004761 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004762 }
4763
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004764 if (!connection->waitQueue.empty()) {
4765 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4766 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004767 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004768 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004769 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004770 }
4771 }
4772 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004773 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004774 }
4775
4776 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004777 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4778 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004779 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004780 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004781 }
4782
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004783 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004784 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4785 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4786 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004787}
4788
Michael Wright3dd60e22019-03-27 22:06:44 +00004789void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4790 const size_t numMonitors = monitors.size();
4791 for (size_t i = 0; i < numMonitors; i++) {
4792 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004793 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004794 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4795 dump += "\n";
4796 }
4797}
4798
Garfield Tan15601662020-09-22 15:32:38 -07004799base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4800 const std::string& name) {
4801#if DEBUG_CHANNEL_CREATION
4802 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004803#endif
4804
Garfield Tan15601662020-09-22 15:32:38 -07004805 std::shared_ptr<InputChannel> serverChannel;
4806 std::unique_ptr<InputChannel> clientChannel;
4807 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4808
4809 if (result) {
4810 return base::Error(result) << "Failed to open input channel pair with name " << name;
4811 }
4812
Michael Wrightd02c5b62014-02-10 15:10:22 -08004813 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004814 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004815 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004816
Garfield Tan15601662020-09-22 15:32:38 -07004817 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004818 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004819 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004820
Michael Wrightd02c5b62014-02-10 15:10:22 -08004821 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4822 } // release lock
4823
4824 // Wake the looper because some connections have changed.
4825 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004826 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004827}
4828
Garfield Tan15601662020-09-22 15:32:38 -07004829base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004830 int32_t displayId, bool isGestureMonitor, const std::string& name, int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07004831 std::shared_ptr<InputChannel> serverChannel;
4832 std::unique_ptr<InputChannel> clientChannel;
4833 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4834 if (result) {
4835 return base::Error(result) << "Failed to open input channel pair with name " << name;
4836 }
4837
Michael Wright3dd60e22019-03-27 22:06:44 +00004838 { // acquire lock
4839 std::scoped_lock _l(mLock);
4840
4841 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004842 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4843 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004844 }
4845
Garfield Tan15601662020-09-22 15:32:38 -07004846 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004847
Garfield Tan15601662020-09-22 15:32:38 -07004848 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004849 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004850 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004851
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004852 auto& monitorsByDisplay =
4853 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004854 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00004855
4856 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004857 }
Garfield Tan15601662020-09-22 15:32:38 -07004858
Michael Wright3dd60e22019-03-27 22:06:44 +00004859 // Wake the looper because some connections have changed.
4860 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004861 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004862}
4863
Garfield Tan15601662020-09-22 15:32:38 -07004864status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004865 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004866 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004867
Garfield Tan15601662020-09-22 15:32:38 -07004868 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004869 if (status) {
4870 return status;
4871 }
4872 } // release lock
4873
4874 // Wake the poll loop because removing the connection may have changed the current
4875 // synchronization state.
4876 mLooper->wake();
4877 return OK;
4878}
4879
Garfield Tan15601662020-09-22 15:32:38 -07004880status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
4881 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004882 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004883 if (connection == nullptr) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004884 ALOGW("Attempted to unregister already unregistered input channel");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004885 return BAD_VALUE;
4886 }
4887
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004888 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004889 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07004890
Michael Wrightd02c5b62014-02-10 15:10:22 -08004891 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004892 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004893 }
4894
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004895 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004896
4897 nsecs_t currentTime = now();
4898 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4899
4900 connection->status = Connection::STATUS_ZOMBIE;
4901 return OK;
4902}
4903
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004904void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
4905 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
4906 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00004907}
4908
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004909void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004910 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00004911 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004912 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004913 std::vector<Monitor>& monitors = it->second;
4914 const size_t numMonitors = monitors.size();
4915 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004916 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004917 monitors.erase(monitors.begin() + i);
4918 break;
4919 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004920 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004921 if (monitors.empty()) {
4922 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004923 } else {
4924 ++it;
4925 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004926 }
4927}
4928
Michael Wright3dd60e22019-03-27 22:06:44 +00004929status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4930 { // acquire lock
4931 std::scoped_lock _l(mLock);
4932 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4933
4934 if (!foundDisplayId) {
4935 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4936 return BAD_VALUE;
4937 }
4938 int32_t displayId = foundDisplayId.value();
4939
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004940 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4941 mTouchStatesByDisplay.find(displayId);
4942 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004943 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4944 return BAD_VALUE;
4945 }
4946
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004947 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00004948 std::optional<int32_t> foundDeviceId;
4949 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004950 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004951 foundDeviceId = state.deviceId;
4952 }
4953 }
4954 if (!foundDeviceId || !state.down) {
4955 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004956 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004957 return BAD_VALUE;
4958 }
4959 int32_t deviceId = foundDeviceId.value();
4960
4961 // Send cancel events to all the input channels we're stealing from.
4962 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004963 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004964 options.deviceId = deviceId;
4965 options.displayId = displayId;
4966 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004967 std::shared_ptr<InputChannel> channel =
4968 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004969 if (channel != nullptr) {
4970 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4971 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004972 }
4973 // Then clear the current touch state so we stop dispatching to them as well.
4974 state.filterNonMonitors();
4975 }
4976 return OK;
4977}
4978
Prabir Pradhan99987712020-11-10 18:43:05 -08004979void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
4980 { // acquire lock
4981 std::scoped_lock _l(mLock);
4982 if (DEBUG_FOCUS) {
4983 const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
4984 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
4985 windowHandle != nullptr ? windowHandle->getName().c_str()
4986 : "token without window");
4987 }
4988
4989 const sp<IBinder> focusedToken =
4990 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4991 if (focusedToken != windowToken) {
4992 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
4993 enabled ? "enable" : "disable");
4994 return;
4995 }
4996
4997 if (enabled == mFocusedWindowRequestedPointerCapture) {
4998 ALOGW("Ignoring request to %s Pointer Capture: "
4999 "window has %s requested pointer capture.",
5000 enabled ? "enable" : "disable", enabled ? "already" : "not");
5001 return;
5002 }
5003
5004 mFocusedWindowRequestedPointerCapture = enabled;
5005 setPointerCaptureLocked(enabled);
5006 } // release lock
5007
5008 // Wake the thread to process command entries.
5009 mLooper->wake();
5010}
5011
Michael Wright3dd60e22019-03-27 22:06:44 +00005012std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5013 const sp<IBinder>& token) {
5014 for (const auto& it : mGestureMonitorsByDisplay) {
5015 const std::vector<Monitor>& monitors = it.second;
5016 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005017 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005018 return it.first;
5019 }
5020 }
5021 }
5022 return std::nullopt;
5023}
5024
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005025sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005026 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005027 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005028 }
5029
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005030 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005031 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005032 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005033 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005034 }
5035 }
Robert Carr4e670e52018-08-15 13:26:12 -07005036
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005037 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005038}
5039
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005040std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5041 sp<Connection> connection = getConnectionLocked(connectionToken);
5042 if (connection == nullptr) {
5043 return "<nullptr>";
5044 }
5045 return connection->getInputChannelName();
5046}
5047
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005048void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005049 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005050 removeByValue(mConnectionsByFd, connection);
5051}
5052
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005053void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5054 const sp<Connection>& connection, uint32_t seq,
5055 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005056 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5057 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005058 commandEntry->connection = connection;
5059 commandEntry->eventTime = currentTime;
5060 commandEntry->seq = seq;
5061 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005062 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005063}
5064
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005065void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5066 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005067 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005068 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005069
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005070 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5071 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005072 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005073 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005074}
5075
Vishnu Nairad321cd2020-08-20 16:40:21 -07005076void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5077 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005078 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5079 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005080 commandEntry->oldToken = oldToken;
5081 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005082 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005083}
5084
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005085void InputDispatcher::onAnrLocked(const Connection& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005086 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5087 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005088 if (connection.waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005089 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005090 connection.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005091 return;
5092 }
5093 /**
5094 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5095 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5096 * has changed. This could cause newer entries to time out before the already dispatched
5097 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5098 * processes the events linearly. So providing information about the oldest entry seems to be
5099 * most useful.
5100 */
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005101 DispatchEntry* oldestEntry = *connection.waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005102 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5103 std::string reason =
5104 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005105 connection.inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005106 ns2ms(currentWait),
5107 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005108 sp<IBinder> connectionToken = connection.inputChannel->getConnectionToken();
5109 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005110
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005111 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5112 &InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible);
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005113 commandEntry->connectionToken = connectionToken;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005114 commandEntry->reason = std::move(reason);
5115 postCommandLocked(std::move(commandEntry));
5116}
5117
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005118void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5119 std::string reason =
5120 StringPrintf("%s does not have a focused window", application->getName().c_str());
5121 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005122
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005123 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5124 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5125 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005126 postCommandLocked(std::move(commandEntry));
5127}
5128
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005129void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5130 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5131 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5132 commandEntry->obscuringPackage = obscuringPackage;
5133 postCommandLocked(std::move(commandEntry));
5134}
5135
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005136void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
5137 const std::string& reason) {
5138 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5139 updateLastAnrStateLocked(windowLabel, reason);
5140}
5141
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005142void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5143 const std::string& reason) {
5144 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005145 updateLastAnrStateLocked(windowLabel, reason);
5146}
5147
5148void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5149 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005150 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005151 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005152 struct tm tm;
5153 localtime_r(&t, &tm);
5154 char timestr[64];
5155 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005156 mLastAnrState.clear();
5157 mLastAnrState += INDENT "ANR:\n";
5158 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005159 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5160 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005161 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005162}
5163
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005164void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005165 mLock.unlock();
5166
5167 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5168
5169 mLock.lock();
5170}
5171
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005172void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005173 sp<Connection> connection = commandEntry->connection;
5174
5175 if (connection->status != Connection::STATUS_ZOMBIE) {
5176 mLock.unlock();
5177
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005178 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005179
5180 mLock.lock();
5181 }
5182}
5183
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005184void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005185 sp<IBinder> oldToken = commandEntry->oldToken;
5186 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005187 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005188 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005189 mLock.lock();
5190}
5191
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005192void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005193 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005194
5195 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5196
5197 mLock.lock();
5198}
5199
5200void InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible(
5201 CommandEntry* commandEntry) {
5202 mLock.unlock();
5203
5204 mPolicy->notifyConnectionUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005205
5206 mLock.lock();
5207
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005208 // stop waking up for events in this connection, it is already not responding
5209 sp<Connection> connection = getConnectionLocked(commandEntry->connectionToken);
5210 if (connection == nullptr) {
5211 return;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005212 }
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005213 cancelEventsForAnrLocked(connection);
5214}
5215
5216void InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5217 mLock.unlock();
5218
5219 mPolicy->notifyConnectionResponsive(commandEntry->connectionToken);
5220
5221 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005222}
5223
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005224void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5225 mLock.unlock();
5226
5227 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5228
5229 mLock.lock();
5230}
5231
Michael Wrightd02c5b62014-02-10 15:10:22 -08005232void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5233 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005234 KeyEntry& entry = *(commandEntry->keyEntry);
5235 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005236
5237 mLock.unlock();
5238
Michael Wright2b3c3302018-03-02 17:19:13 +00005239 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005240 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005241 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005242 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5243 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005244 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005245 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005246
5247 mLock.lock();
5248
5249 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005250 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005251 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005252 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005253 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005254 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5255 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005256 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005257}
5258
chaviwfd6d3512019-03-25 13:23:49 -07005259void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5260 mLock.unlock();
5261 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5262 mLock.lock();
5263}
5264
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005265/**
5266 * Connection is responsive if it has no events in the waitQueue that are older than the
5267 * current time.
5268 */
5269static bool isConnectionResponsive(const Connection& connection) {
5270 const nsecs_t currentTime = now();
5271 for (const DispatchEntry* entry : connection.waitQueue) {
5272 if (entry->timeoutTime < currentTime) {
5273 return false;
5274 }
5275 }
5276 return true;
5277}
5278
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005279void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005280 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005281 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005282 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005283 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005284
5285 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005286 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005287 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005288 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005289 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005290 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005291 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005292 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005293 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5294 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005295 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005296 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005297
5298 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005299 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005300 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005301 restartEvent =
5302 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005303 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005304 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005305 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5306 handled);
5307 } else {
5308 restartEvent = false;
5309 }
5310
5311 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005312 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005313 // contents of the wait queue to have been drained, so we need to double-check
5314 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005315 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5316 if (dispatchEntryIt != connection->waitQueue.end()) {
5317 dispatchEntry = *dispatchEntryIt;
5318 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005319 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5320 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005321 if (!connection->responsive) {
5322 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005323 if (connection->responsive) {
5324 // The connection was unresponsive, and now it's responsive. Tell the policy
5325 // about it so that it can stop ANR.
5326 std::unique_ptr<CommandEntry> connectionResponsiveCommand =
5327 std::make_unique<CommandEntry>(
5328 &InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible);
5329 connectionResponsiveCommand->connectionToken = connectionToken;
5330 postCommandLocked(std::move(connectionResponsiveCommand));
5331 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005332 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005333 traceWaitQueueLength(connection);
5334 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005335 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005336 traceOutboundQueueLength(connection);
5337 } else {
5338 releaseDispatchEntry(dispatchEntry);
5339 }
5340 }
5341
5342 // Start the next dispatch cycle for this connection.
5343 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005344}
5345
5346bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005347 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005348 KeyEntry& keyEntry, bool handled) {
5349 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005350 if (!handled) {
5351 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005352 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005353 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005354 return false;
5355 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005356
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005357 // Get the fallback key state.
5358 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005359 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005360 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005361 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005362 connection->inputState.removeFallbackKey(originalKeyCode);
5363 }
5364
5365 if (handled || !dispatchEntry->hasForegroundTarget()) {
5366 // If the application handles the original key for which we previously
5367 // generated a fallback or if the window is not a foreground window,
5368 // then cancel the associated fallback key, if any.
5369 if (fallbackKeyCode != -1) {
5370 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005371#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005372 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005373 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005374 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005375#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005376 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005377 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005378
5379 mLock.unlock();
5380
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005381 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005382 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005383
5384 mLock.lock();
5385
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005386 // Cancel the fallback key.
5387 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005388 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005389 "application handled the original non-fallback key "
5390 "or is no longer a foreground target, "
5391 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005392 options.keyCode = fallbackKeyCode;
5393 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005394 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005395 connection->inputState.removeFallbackKey(originalKeyCode);
5396 }
5397 } else {
5398 // If the application did not handle a non-fallback key, first check
5399 // that we are in a good state to perform unhandled key event processing
5400 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005401 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005402 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005403#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005404 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005405 "since this is not an initial down. "
5406 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005407 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005408#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005409 return false;
5410 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005411
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005412 // Dispatch the unhandled key to the policy.
5413#if DEBUG_OUTBOUND_EVENT_DETAILS
5414 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005415 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005416 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005417#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005418 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005419
5420 mLock.unlock();
5421
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005422 bool fallback =
5423 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005424 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005425
5426 mLock.lock();
5427
5428 if (connection->status != Connection::STATUS_NORMAL) {
5429 connection->inputState.removeFallbackKey(originalKeyCode);
5430 return false;
5431 }
5432
5433 // Latch the fallback keycode for this key on an initial down.
5434 // The fallback keycode cannot change at any other point in the lifecycle.
5435 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005436 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005437 fallbackKeyCode = event.getKeyCode();
5438 } else {
5439 fallbackKeyCode = AKEYCODE_UNKNOWN;
5440 }
5441 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5442 }
5443
5444 ALOG_ASSERT(fallbackKeyCode != -1);
5445
5446 // Cancel the fallback key if the policy decides not to send it anymore.
5447 // We will continue to dispatch the key to the policy but we will no
5448 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005449 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5450 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005451#if DEBUG_OUTBOUND_EVENT_DETAILS
5452 if (fallback) {
5453 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005454 "as a fallback for %d, but on the DOWN it had requested "
5455 "to send %d instead. Fallback canceled.",
5456 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005457 } else {
5458 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005459 "but on the DOWN it had requested to send %d. "
5460 "Fallback canceled.",
5461 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005462 }
5463#endif
5464
5465 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5466 "canceling fallback, policy no longer desires it");
5467 options.keyCode = fallbackKeyCode;
5468 synthesizeCancelationEventsForConnectionLocked(connection, options);
5469
5470 fallback = false;
5471 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005472 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005473 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005474 }
5475 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005476
5477#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005478 {
5479 std::string msg;
5480 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5481 connection->inputState.getFallbackKeys();
5482 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005483 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005484 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005485 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005486 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005487 }
5488#endif
5489
5490 if (fallback) {
5491 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005492 keyEntry.eventTime = event.getEventTime();
5493 keyEntry.deviceId = event.getDeviceId();
5494 keyEntry.source = event.getSource();
5495 keyEntry.displayId = event.getDisplayId();
5496 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5497 keyEntry.keyCode = fallbackKeyCode;
5498 keyEntry.scanCode = event.getScanCode();
5499 keyEntry.metaState = event.getMetaState();
5500 keyEntry.repeatCount = event.getRepeatCount();
5501 keyEntry.downTime = event.getDownTime();
5502 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005503
5504#if DEBUG_OUTBOUND_EVENT_DETAILS
5505 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005506 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005507 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005508#endif
5509 return true; // restart the event
5510 } else {
5511#if DEBUG_OUTBOUND_EVENT_DETAILS
5512 ALOGD("Unhandled key event: No fallback key.");
5513#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005514
5515 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005516 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005517 }
5518 }
5519 return false;
5520}
5521
5522bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005523 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005524 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005525 return false;
5526}
5527
5528void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5529 mLock.unlock();
5530
5531 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5532
5533 mLock.lock();
5534}
5535
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005536KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
5537 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08005538 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08005539 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
5540 entry.repeatCount, entry.downTime, entry.eventTime);
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005541 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005542}
5543
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005544void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5545 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005546 // TODO Write some statistics about how long we spend waiting.
5547}
5548
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005549/**
5550 * Report the touch event latency to the statsd server.
5551 * Input events are reported for statistics if:
5552 * - This is a touchscreen event
5553 * - InputFilter is not enabled
5554 * - Event is not injected or synthesized
5555 *
5556 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5557 * from getting aggregated with the "old" data.
5558 */
5559void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5560 REQUIRES(mLock) {
5561 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5562 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5563 if (!reportForStatistics) {
5564 return;
5565 }
5566
5567 if (mTouchStatistics.shouldReport()) {
5568 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5569 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5570 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5571 mTouchStatistics.reset();
5572 }
5573 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5574 mTouchStatistics.addValue(latencyMicros);
5575}
5576
Michael Wrightd02c5b62014-02-10 15:10:22 -08005577void InputDispatcher::traceInboundQueueLengthLocked() {
5578 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005579 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005580 }
5581}
5582
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005583void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005584 if (ATRACE_ENABLED()) {
5585 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005586 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005587 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005588 }
5589}
5590
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005591void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005592 if (ATRACE_ENABLED()) {
5593 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005594 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005595 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005596 }
5597}
5598
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005599void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005600 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005601
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005602 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005603 dumpDispatchStateLocked(dump);
5604
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005605 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005606 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005607 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005608 }
5609}
5610
5611void InputDispatcher::monitor() {
5612 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005613 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005614 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005615 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005616}
5617
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005618/**
5619 * Wake up the dispatcher and wait until it processes all events and commands.
5620 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5621 * this method can be safely called from any thread, as long as you've ensured that
5622 * the work you are interested in completing has already been queued.
5623 */
5624bool InputDispatcher::waitForIdle() {
5625 /**
5626 * Timeout should represent the longest possible time that a device might spend processing
5627 * events and commands.
5628 */
5629 constexpr std::chrono::duration TIMEOUT = 100ms;
5630 std::unique_lock lock(mLock);
5631 mLooper->wake();
5632 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5633 return result == std::cv_status::no_timeout;
5634}
5635
Vishnu Naire798b472020-07-23 13:52:21 -07005636/**
5637 * Sets focus to the window identified by the token. This must be called
5638 * after updating any input window handles.
5639 *
5640 * Params:
5641 * request.token - input channel token used to identify the window that should gain focus.
5642 * request.focusedToken - the token that the caller expects currently to be focused. If the
5643 * specified token does not match the currently focused window, this request will be dropped.
5644 * If the specified focused token matches the currently focused window, the call will succeed.
5645 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5646 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5647 * when requesting the focus change. This determines which request gets
5648 * precedence if there is a focus change request from another source such as pointer down.
5649 */
Vishnu Nair958da932020-08-21 17:12:37 -07005650void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5651 { // acquire lock
5652 std::scoped_lock _l(mLock);
5653
5654 const int32_t displayId = request.displayId;
5655 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5656 if (request.focusedToken && oldFocusedToken != request.focusedToken) {
5657 ALOGD_IF(DEBUG_FOCUS,
5658 "setFocusedWindow on display %" PRId32
5659 " ignored, reason: focusedToken is not focused",
5660 displayId);
5661 return;
5662 }
5663
5664 mPendingFocusRequests.erase(displayId);
5665 FocusResult result = handleFocusRequestLocked(request);
5666 if (result == FocusResult::NOT_VISIBLE) {
5667 // The requested window is not currently visible. Wait for the window to become visible
5668 // and then provide it focus. This is to handle situations where a user action triggers
5669 // a new window to appear. We want to be able to queue any key events after the user
5670 // action and deliver it to the newly focused window. In order for this to happen, we
5671 // take focus from the currently focused window so key events can be queued.
5672 ALOGD_IF(DEBUG_FOCUS,
5673 "setFocusedWindow on display %" PRId32
5674 " pending, reason: window is not visible",
5675 displayId);
5676 mPendingFocusRequests[displayId] = request;
5677 onFocusChangedLocked(oldFocusedToken, nullptr, displayId,
5678 "setFocusedWindow_AwaitingWindowVisibility");
5679 } else if (result != FocusResult::OK) {
5680 ALOGW("setFocusedWindow on display %" PRId32 " ignored, reason:%s", displayId,
5681 typeToString(result));
5682 }
5683 } // release lock
5684 // Wake up poll loop since it may need to make new input dispatching choices.
5685 mLooper->wake();
5686}
5687
5688InputDispatcher::FocusResult InputDispatcher::handleFocusRequestLocked(
5689 const FocusRequest& request) {
5690 const int32_t displayId = request.displayId;
5691 const sp<IBinder> newFocusedToken = request.token;
5692 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5693
5694 if (oldFocusedToken == request.token) {
5695 ALOGD_IF(DEBUG_FOCUS,
5696 "setFocusedWindow on display %" PRId32 " ignored, reason: already focused",
5697 displayId);
5698 return FocusResult::OK;
5699 }
5700
5701 FocusResult result = checkTokenFocusableLocked(newFocusedToken, displayId);
5702 if (result != FocusResult::OK) {
5703 return result;
5704 }
5705
5706 std::string_view reason =
5707 (request.focusedToken) ? "setFocusedWindow_FocusCheck" : "setFocusedWindow";
5708 onFocusChangedLocked(oldFocusedToken, newFocusedToken, displayId, reason);
5709 return FocusResult::OK;
5710}
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005711
Vishnu Nairad321cd2020-08-20 16:40:21 -07005712void InputDispatcher::onFocusChangedLocked(const sp<IBinder>& oldFocusedToken,
5713 const sp<IBinder>& newFocusedToken, int32_t displayId,
5714 std::string_view reason) {
5715 if (oldFocusedToken) {
5716 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(oldFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005717 if (focusedInputChannel) {
5718 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5719 "focus left window");
5720 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005721 enqueueFocusEventLocked(oldFocusedToken, false /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005722 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005723 mFocusedWindowTokenByDisplay.erase(displayId);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005724 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005725 if (newFocusedToken) {
5726 mFocusedWindowTokenByDisplay[displayId] = newFocusedToken;
5727 enqueueFocusEventLocked(newFocusedToken, true /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005728 }
5729
Prabir Pradhan99987712020-11-10 18:43:05 -08005730 // If a window has pointer capture, then it must have focus. We need to ensure that this
5731 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
5732 // If the window loses focus before it loses pointer capture, then the window can be in a state
5733 // where it has pointer capture but not focus, violating the contract. Therefore we must
5734 // dispatch the pointer capture event before the focus event. Since focus events are added to
5735 // the front of the queue (above), we add the pointer capture event to the front of the queue
5736 // after the focus events are added. This ensures the pointer capture event ends up at the
5737 // front.
5738 disablePointerCaptureForcedLocked();
5739
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005740 if (mFocusedDisplayId == displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005741 notifyFocusChangedLocked(oldFocusedToken, newFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005742 }
5743}
Vishnu Nair958da932020-08-21 17:12:37 -07005744
Prabir Pradhan99987712020-11-10 18:43:05 -08005745void InputDispatcher::disablePointerCaptureForcedLocked() {
5746 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
5747 return;
5748 }
5749
5750 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
5751
5752 if (mFocusedWindowRequestedPointerCapture) {
5753 mFocusedWindowRequestedPointerCapture = false;
5754 setPointerCaptureLocked(false);
5755 }
5756
5757 if (!mWindowTokenWithPointerCapture) {
5758 // No need to send capture changes because no window has capture.
5759 return;
5760 }
5761
5762 if (mPendingEvent != nullptr) {
5763 // Move the pending event to the front of the queue. This will give the chance
5764 // for the pending event to be dropped if it is a captured event.
5765 mInboundQueue.push_front(mPendingEvent);
5766 mPendingEvent = nullptr;
5767 }
5768
5769 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
5770 false /* hasCapture */);
5771 mInboundQueue.push_front(std::move(entry));
5772}
5773
Vishnu Nair958da932020-08-21 17:12:37 -07005774/**
5775 * Checks if the window token can be focused on a display. The token can be focused if there is
5776 * at least one window handle that is visible with the same token and all window handles with the
5777 * same token are focusable.
5778 *
5779 * In the case of mirroring, two windows may share the same window token and their visibility
5780 * might be different. Example, the mirrored window can cover the window its mirroring. However,
5781 * we expect the focusability of the windows to match since its hard to reason why one window can
5782 * receive focus events and the other cannot when both are backed by the same input channel.
5783 */
5784InputDispatcher::FocusResult InputDispatcher::checkTokenFocusableLocked(const sp<IBinder>& token,
5785 int32_t displayId) const {
5786 bool allWindowsAreFocusable = true;
5787 bool visibleWindowFound = false;
5788 bool windowFound = false;
5789 for (const sp<InputWindowHandle>& window : getWindowHandlesLocked(displayId)) {
5790 if (window->getToken() != token) {
5791 continue;
5792 }
5793 windowFound = true;
5794 if (window->getInfo()->visible) {
5795 // Check if at least a single window is visible.
5796 visibleWindowFound = true;
5797 }
5798 if (!window->getInfo()->focusable) {
5799 // Check if all windows with the window token are focusable.
5800 allWindowsAreFocusable = false;
5801 break;
5802 }
5803 }
5804
5805 if (!windowFound) {
5806 return FocusResult::NO_WINDOW;
5807 }
5808 if (!allWindowsAreFocusable) {
5809 return FocusResult::NOT_FOCUSABLE;
5810 }
5811 if (!visibleWindowFound) {
5812 return FocusResult::NOT_VISIBLE;
5813 }
5814
5815 return FocusResult::OK;
5816}
Prabir Pradhan99987712020-11-10 18:43:05 -08005817
5818void InputDispatcher::setPointerCaptureLocked(bool enabled) {
5819 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5820 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
5821 commandEntry->enabled = enabled;
5822 postCommandLocked(std::move(commandEntry));
5823}
5824
5825void InputDispatcher::doSetPointerCaptureLockedInterruptible(
5826 android::inputdispatcher::CommandEntry* commandEntry) {
5827 mLock.unlock();
5828
5829 mPolicy->setPointerCapture(commandEntry->enabled);
5830
5831 mLock.lock();
5832}
5833
Garfield Tane84e6f92019-08-29 17:28:41 -07005834} // namespace android::inputdispatcher