blob: ed4f05a15fc66ea721c570d89c386f9c15a3ec72 [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),
457 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800458 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800459 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800460
Yi Kong9b14ac62018-07-17 13:48:38 -0700461 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800462
463 policy->getDispatcherConfiguration(&mConfig);
464}
465
466InputDispatcher::~InputDispatcher() {
467 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800468 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800469
470 resetKeyRepeatLocked();
471 releasePendingEventLocked();
472 drainInboundQueueLocked();
473 }
474
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700475 while (!mConnectionsByFd.empty()) {
476 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700477 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800478 }
479}
480
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700481status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700482 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700483 return ALREADY_EXISTS;
484 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700485 mThread = std::make_unique<InputThread>(
486 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
487 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700488}
489
490status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700491 if (mThread && mThread->isCallingThread()) {
492 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700493 return INVALID_OPERATION;
494 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700495 mThread.reset();
496 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700497}
498
Michael Wrightd02c5b62014-02-10 15:10:22 -0800499void InputDispatcher::dispatchOnce() {
500 nsecs_t nextWakeupTime = LONG_LONG_MAX;
501 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800502 std::scoped_lock _l(mLock);
503 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800504
505 // Run a dispatch loop if there are no pending commands.
506 // The dispatch loop might enqueue commands to run afterwards.
507 if (!haveCommandsLocked()) {
508 dispatchOnceInnerLocked(&nextWakeupTime);
509 }
510
511 // Run all pending commands if there are any.
512 // If any commands were run then force the next poll to wake up immediately.
513 if (runCommandsLockedInterruptible()) {
514 nextWakeupTime = LONG_LONG_MIN;
515 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800516
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700517 // If we are still waiting for ack on some events,
518 // we might have to wake up earlier to check if an app is anr'ing.
519 const nsecs_t nextAnrCheck = processAnrsLocked();
520 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
521
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800522 // We are about to enter an infinitely long sleep, because we have no commands or
523 // pending or queued events
524 if (nextWakeupTime == LONG_LONG_MAX) {
525 mDispatcherEnteredIdle.notify_all();
526 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800527 } // release lock
528
529 // Wait for callback or timeout or wake. (make sure we round up, not down)
530 nsecs_t currentTime = now();
531 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
532 mLooper->pollOnce(timeoutMillis);
533}
534
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700535/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500536 * Raise ANR if there is no focused window.
537 * Before the ANR is raised, do a final state check:
538 * 1. The currently focused application must be the same one we are waiting for.
539 * 2. Ensure we still don't have a focused window.
540 */
541void InputDispatcher::processNoFocusedWindowAnrLocked() {
542 // Check if the application that we are waiting for is still focused.
543 std::shared_ptr<InputApplicationHandle> focusedApplication =
544 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
545 if (focusedApplication == nullptr ||
546 focusedApplication->getApplicationToken() !=
547 mAwaitedFocusedApplication->getApplicationToken()) {
548 // Unexpected because we should have reset the ANR timer when focused application changed
549 ALOGE("Waited for a focused window, but focused application has already changed to %s",
550 focusedApplication->getName().c_str());
551 return; // The focused application has changed.
552 }
553
554 const sp<InputWindowHandle>& focusedWindowHandle =
555 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
556 if (focusedWindowHandle != nullptr) {
557 return; // We now have a focused window. No need for ANR.
558 }
559 onAnrLocked(mAwaitedFocusedApplication);
560}
561
562/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700563 * Check if any of the connections' wait queues have events that are too old.
564 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
565 * Return the time at which we should wake up next.
566 */
567nsecs_t InputDispatcher::processAnrsLocked() {
568 const nsecs_t currentTime = now();
569 nsecs_t nextAnrCheck = LONG_LONG_MAX;
570 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
571 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
572 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500573 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700574 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500575 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700576 return LONG_LONG_MIN;
577 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500578 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700579 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
580 }
581 }
582
583 // Check if any connection ANRs are due
584 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
585 if (currentTime < nextAnrCheck) { // most likely scenario
586 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
587 }
588
589 // If we reached here, we have an unresponsive connection.
590 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
591 if (connection == nullptr) {
592 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
593 return nextAnrCheck;
594 }
595 connection->responsive = false;
596 // Stop waking up for this unresponsive connection
597 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -0500598 onAnrLocked(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700599 return LONG_LONG_MIN;
600}
601
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500602std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700603 sp<InputWindowHandle> window = getWindowHandleLocked(token);
604 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500605 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700606 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500607 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700608}
609
Michael Wrightd02c5b62014-02-10 15:10:22 -0800610void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
611 nsecs_t currentTime = now();
612
Jeff Browndc5992e2014-04-11 01:27:26 -0700613 // Reset the key repeat timer whenever normal dispatch is suspended while the
614 // device is in a non-interactive state. This is to ensure that we abort a key
615 // repeat if the device is just coming out of sleep.
616 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800617 resetKeyRepeatLocked();
618 }
619
620 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
621 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100622 if (DEBUG_FOCUS) {
623 ALOGD("Dispatch frozen. Waiting some more.");
624 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800625 return;
626 }
627
628 // Optimize latency of app switches.
629 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
630 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
631 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
632 if (mAppSwitchDueTime < *nextWakeupTime) {
633 *nextWakeupTime = mAppSwitchDueTime;
634 }
635
636 // Ready to start a new event.
637 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700638 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700639 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800640 if (isAppSwitchDue) {
641 // The inbound queue is empty so the app switch key we were waiting
642 // for will never arrive. Stop waiting for it.
643 resetPendingAppSwitchLocked(false);
644 isAppSwitchDue = false;
645 }
646
647 // Synthesize a key repeat if appropriate.
648 if (mKeyRepeatState.lastKeyEntry) {
649 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
650 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
651 } else {
652 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
653 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
654 }
655 }
656 }
657
658 // Nothing to do if there is no pending event.
659 if (!mPendingEvent) {
660 return;
661 }
662 } else {
663 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700664 mPendingEvent = mInboundQueue.front();
665 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800666 traceInboundQueueLengthLocked();
667 }
668
669 // Poke user activity for this event.
670 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700671 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800672 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800673 }
674
675 // Now we have an event to dispatch.
676 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700677 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800678 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700679 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800680 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700681 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800682 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700683 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800684 }
685
686 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700687 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800688 }
689
690 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700691 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700692 const ConfigurationChangedEntry& typedEntry =
693 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700694 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700695 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700696 break;
697 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800698
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700699 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700700 const DeviceResetEntry& typedEntry =
701 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700702 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700703 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700704 break;
705 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800706
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100707 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700708 std::shared_ptr<FocusEntry> typedEntry =
709 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100710 dispatchFocusLocked(currentTime, typedEntry);
711 done = true;
712 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
713 break;
714 }
715
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700716 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700717 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700718 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700719 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700720 resetPendingAppSwitchLocked(true);
721 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700722 } else if (dropReason == DropReason::NOT_DROPPED) {
723 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700724 }
725 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700726 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700727 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700728 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700729 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
730 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700731 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700732 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700733 break;
734 }
735
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700736 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700737 std::shared_ptr<MotionEntry> motionEntry =
738 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700739 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
740 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800741 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700742 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700743 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700744 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700745 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
746 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700747 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700748 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700749 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800750 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800751 }
752
753 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700754 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700755 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800756 }
Michael Wright3a981722015-06-10 15:26:13 +0100757 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800758
759 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700760 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800761 }
762}
763
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700764/**
765 * Return true if the events preceding this incoming motion event should be dropped
766 * Return false otherwise (the default behaviour)
767 */
768bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700769 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700770 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700771
772 // Optimize case where the current application is unresponsive and the user
773 // decides to touch a window in a different application.
774 // If the application takes too long to catch up then we drop all events preceding
775 // the touch into the other window.
776 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700777 int32_t displayId = motionEntry.displayId;
778 int32_t x = static_cast<int32_t>(
779 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
780 int32_t y = static_cast<int32_t>(
781 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
782 sp<InputWindowHandle> touchedWindowHandle =
783 findTouchedWindowAtLocked(displayId, x, y, nullptr);
784 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700785 touchedWindowHandle->getApplicationToken() !=
786 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700787 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700788 ALOGI("Pruning input queue because user touched a different application while waiting "
789 "for %s",
790 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700791 return true;
792 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700793
794 // Alternatively, maybe there's a gesture monitor that could handle this event
795 std::vector<TouchedMonitor> gestureMonitors =
796 findTouchedGestureMonitorsLocked(displayId, {});
797 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
798 sp<Connection> connection =
799 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000800 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700801 // This monitor could take more input. Drop all events preceding this
802 // event, so that gesture monitor could get a chance to receive the stream
803 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
804 "responsive gesture monitor that may handle the event",
805 mAwaitedFocusedApplication->getName().c_str());
806 return true;
807 }
808 }
809 }
810
811 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
812 // yet been processed by some connections, the dispatcher will wait for these motion
813 // events to be processed before dispatching the key event. This is because these motion events
814 // may cause a new window to be launched, which the user might expect to receive focus.
815 // To prevent waiting forever for such events, just send the key to the currently focused window
816 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
817 ALOGD("Received a new pointer down event, stop waiting for events to process and "
818 "just send the pending key event to the focused window.");
819 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700820 }
821 return false;
822}
823
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700824bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700825 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700826 mInboundQueue.push_back(std::move(newEntry));
827 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800828 traceInboundQueueLengthLocked();
829
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700830 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700831 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700832 // Optimize app switch latency.
833 // If the application takes too long to catch up then we drop all events preceding
834 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700835 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700836 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700837 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700838 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700839 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700840 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800841#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700842 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800843#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700844 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700845 mAppSwitchSawKeyDown = false;
846 needWake = true;
847 }
848 }
849 }
850 break;
851 }
852
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700853 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700854 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
855 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700856 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800857 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700858 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800859 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100860 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700861 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
862 break;
863 }
864 case EventEntry::Type::CONFIGURATION_CHANGED:
865 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700866 // nothing to do
867 break;
868 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800869 }
870
871 return needWake;
872}
873
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700874void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700875 mRecentQueue.push_back(entry);
876 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700877 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800878 }
879}
880
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700881sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700882 int32_t y, TouchState* touchState,
883 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700884 bool addPortalWindows) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700885 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
886 LOG_ALWAYS_FATAL(
887 "Must provide a valid touch state if adding portal windows or outside targets");
888 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800889 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700890 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800891 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800892 const InputWindowInfo* windowInfo = windowHandle->getInfo();
893 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100894 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800895
896 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100897 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
898 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
899 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800900 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800901 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700902 if (portalToDisplayId != ADISPLAY_ID_NONE &&
903 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800904 if (addPortalWindows) {
905 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700906 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800907 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700908 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700909 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800910 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800911 // Found window.
912 return windowHandle;
913 }
914 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800915
Michael Wright44753b12020-07-08 13:48:11 +0100916 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700917 touchState->addOrUpdateWindow(windowHandle,
918 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
919 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800920 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800921 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800922 }
923 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700924 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800925}
926
Garfield Tane84e6f92019-08-29 17:28:41 -0700927std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700928 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000929 std::vector<TouchedMonitor> touchedMonitors;
930
931 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
932 addGestureMonitors(monitors, touchedMonitors);
933 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
934 const InputWindowInfo* windowInfo = portalWindow->getInfo();
935 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700936 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
937 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000938 }
939 return touchedMonitors;
940}
941
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700942void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800943 const char* reason;
944 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700945 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800946#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700947 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800948#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700949 reason = "inbound event was dropped because the policy consumed it";
950 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700951 case DropReason::DISABLED:
952 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700953 ALOGI("Dropped event because input dispatch is disabled.");
954 }
955 reason = "inbound event was dropped because input dispatch is disabled";
956 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700957 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700958 ALOGI("Dropped event because of pending overdue app switch.");
959 reason = "inbound event was dropped because of pending overdue app switch";
960 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700961 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700962 ALOGI("Dropped event because the current application is not responding and the user "
963 "has started interacting with a different application.");
964 reason = "inbound event was dropped because the current application is not responding "
965 "and the user has started interacting with a different application";
966 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700967 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700968 ALOGI("Dropped event because it is stale.");
969 reason = "inbound event was dropped because it is stale";
970 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700971 case DropReason::NOT_DROPPED: {
972 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700973 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700974 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800975 }
976
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700977 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700978 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800979 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
980 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700981 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800982 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700983 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700984 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
985 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700986 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
987 synthesizeCancelationEventsForAllConnectionsLocked(options);
988 } else {
989 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
990 synthesizeCancelationEventsForAllConnectionsLocked(options);
991 }
992 break;
993 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100994 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700995 case EventEntry::Type::CONFIGURATION_CHANGED:
996 case EventEntry::Type::DEVICE_RESET: {
997 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
998 break;
999 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001000 }
1001}
1002
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001003static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001004 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1005 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001006}
1007
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001008bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1009 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1010 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1011 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001012}
1013
1014bool InputDispatcher::isAppSwitchPendingLocked() {
1015 return mAppSwitchDueTime != LONG_LONG_MAX;
1016}
1017
1018void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1019 mAppSwitchDueTime = LONG_LONG_MAX;
1020
1021#if DEBUG_APP_SWITCH
1022 if (handled) {
1023 ALOGD("App switch has arrived.");
1024 } else {
1025 ALOGD("App switch was abandoned.");
1026 }
1027#endif
1028}
1029
Michael Wrightd02c5b62014-02-10 15:10:22 -08001030bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001031 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001032}
1033
1034bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001035 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001036 return false;
1037 }
1038
1039 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001040 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001041 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001042 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001043 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001044
1045 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001046 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001047 return true;
1048}
1049
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001050void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1051 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001052}
1053
1054void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001055 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001056 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001057 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001058 releaseInboundEventLocked(entry);
1059 }
1060 traceInboundQueueLengthLocked();
1061}
1062
1063void InputDispatcher::releasePendingEventLocked() {
1064 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001065 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001066 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001067 }
1068}
1069
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001070void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001071 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001072 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001073#if DEBUG_DISPATCH_CYCLE
1074 ALOGD("Injected inbound event was dropped.");
1075#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001076 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001077 }
1078 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001079 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080 }
1081 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001082}
1083
1084void InputDispatcher::resetKeyRepeatLocked() {
1085 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001086 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001087 }
1088}
1089
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001090std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1091 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001092
Michael Wright2e732952014-09-24 13:26:59 -07001093 uint32_t policyFlags = entry->policyFlags &
1094 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001095
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001096 std::shared_ptr<KeyEntry> newEntry =
1097 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1098 entry->source, entry->displayId, policyFlags, entry->action,
1099 entry->flags, entry->keyCode, entry->scanCode,
1100 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001101
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001102 newEntry->syntheticRepeat = true;
1103 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001104 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001105 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001106}
1107
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001108bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001109 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001110#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001111 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001112#endif
1113
1114 // Reset key repeating in case a keyboard device was added or removed or something.
1115 resetKeyRepeatLocked();
1116
1117 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001118 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1119 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001120 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001121 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001122 return true;
1123}
1124
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001125bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1126 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001127#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001128 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1129 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130#endif
1131
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001132 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001133 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001134 synthesizeCancelationEventsForAllConnectionsLocked(options);
1135 return true;
1136}
1137
Vishnu Nairad321cd2020-08-20 16:40:21 -07001138void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001139 std::string_view reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001140 if (mPendingEvent != nullptr) {
1141 // Move the pending event to the front of the queue. This will give the chance
1142 // for the pending event to get dispatched to the newly focused window
1143 mInboundQueue.push_front(mPendingEvent);
1144 mPendingEvent = nullptr;
1145 }
1146
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001147 std::unique_ptr<FocusEntry> focusEntry =
1148 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1149 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001150
1151 // This event should go to the front of the queue, but behind all other focus events
1152 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001153 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001154 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001155 [](const std::shared_ptr<EventEntry>& event) {
1156 return event->type == EventEntry::Type::FOCUS;
1157 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001158
1159 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001160 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001161}
1162
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001163void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001164 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001165 if (channel == nullptr) {
1166 return; // Window has gone away
1167 }
1168 InputTarget target;
1169 target.inputChannel = channel;
1170 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1171 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001172 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1173 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001174 std::string reason = std::string("reason=").append(entry->reason);
1175 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001176 dispatchEventLocked(currentTime, entry, {target});
1177}
1178
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001179bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001180 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001181 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001182 if (!entry->dispatchInProgress) {
1183 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1184 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1185 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1186 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001187 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001188 // We have seen two identical key downs in a row which indicates that the device
1189 // driver is automatically generating key repeats itself. We take note of the
1190 // repeat here, but we disable our own next key repeat timer since it is clear that
1191 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001192 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1193 // Make sure we don't get key down from a different device. If a different
1194 // device Id has same key pressed down, the new device Id will replace the
1195 // current one to hold the key repeat with repeat count reset.
1196 // In the future when got a KEY_UP on the device id, drop it and do not
1197 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001198 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1199 resetKeyRepeatLocked();
1200 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1201 } else {
1202 // Not a repeat. Save key down state in case we do see a repeat later.
1203 resetKeyRepeatLocked();
1204 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1205 }
1206 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001207 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1208 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001209 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001210#if DEBUG_INBOUND_EVENT_DETAILS
1211 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1212#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001213 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001214 resetKeyRepeatLocked();
1215 }
1216
1217 if (entry->repeatCount == 1) {
1218 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1219 } else {
1220 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1221 }
1222
1223 entry->dispatchInProgress = true;
1224
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001225 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001226 }
1227
1228 // Handle case where the policy asked us to try again later last time.
1229 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1230 if (currentTime < entry->interceptKeyWakeupTime) {
1231 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1232 *nextWakeupTime = entry->interceptKeyWakeupTime;
1233 }
1234 return false; // wait until next wakeup
1235 }
1236 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1237 entry->interceptKeyWakeupTime = 0;
1238 }
1239
1240 // Give the policy a chance to intercept the key.
1241 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1242 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001243 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001244 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001245 sp<IBinder> focusedWindowToken =
1246 getValueByKey(mFocusedWindowTokenByDisplay, getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001247 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001248 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001249 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001250 return false; // wait for the command to run
1251 } else {
1252 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1253 }
1254 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001255 if (*dropReason == DropReason::NOT_DROPPED) {
1256 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001257 }
1258 }
1259
1260 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001261 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001262 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001263 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1264 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001265 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001266 return true;
1267 }
1268
1269 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001270 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001271 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001272 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001273 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001274 return false;
1275 }
1276
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001277 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001278 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001279 return true;
1280 }
1281
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001282 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001283 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001284
1285 // Dispatch the key.
1286 dispatchEventLocked(currentTime, entry, inputTargets);
1287 return true;
1288}
1289
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001290void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001291#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001292 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001293 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1294 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001295 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1296 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1297 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001298#endif
1299}
1300
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001301bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001302 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001303 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001304 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001305 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001306 entry->dispatchInProgress = true;
1307
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001308 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001309 }
1310
1311 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001312 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001313 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001314 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1315 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001316 return true;
1317 }
1318
1319 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1320
1321 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001322 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001323
1324 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001325 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001326 if (isPointerEvent) {
1327 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001328 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001329 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001330 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001331 } else {
1332 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001333 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001334 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001335 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001336 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001337 return false;
1338 }
1339
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001340 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001341 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001342 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1343 return true;
1344 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001345 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001346 CancelationOptions::Mode mode(isPointerEvent
1347 ? CancelationOptions::CANCEL_POINTER_EVENTS
1348 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1349 CancelationOptions options(mode, "input event injection failed");
1350 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001351 return true;
1352 }
1353
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001354 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001355 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001356
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001357 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001358 std::unordered_map<int32_t, TouchState>::iterator it =
1359 mTouchStatesByDisplay.find(entry->displayId);
1360 if (it != mTouchStatesByDisplay.end()) {
1361 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001362 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001363 // The event has gone through these portal windows, so we add monitoring targets of
1364 // the corresponding displays as well.
1365 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001366 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001367 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001368 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001369 }
1370 }
1371 }
1372 }
1373
Michael Wrightd02c5b62014-02-10 15:10:22 -08001374 // Dispatch the motion.
1375 if (conflictingPointerActions) {
1376 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001377 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001378 synthesizeCancelationEventsForAllConnectionsLocked(options);
1379 }
1380 dispatchEventLocked(currentTime, entry, inputTargets);
1381 return true;
1382}
1383
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001384void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001385#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001386 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001387 ", policyFlags=0x%x, "
1388 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1389 "metaState=0x%x, buttonState=0x%x,"
1390 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001391 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1392 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1393 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001394
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001395 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001396 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001397 "x=%f, y=%f, pressure=%f, size=%f, "
1398 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1399 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001400 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1401 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1402 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1403 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1404 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1405 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1406 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1407 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1408 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1409 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001410 }
1411#endif
1412}
1413
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001414void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1415 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001416 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001417 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001418#if DEBUG_DISPATCH_CYCLE
1419 ALOGD("dispatchEventToCurrentInputTargets");
1420#endif
1421
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001422 updateInteractionTokensLocked(*eventEntry, inputTargets);
1423
Michael Wrightd02c5b62014-02-10 15:10:22 -08001424 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1425
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001426 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001427
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001428 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001429 sp<Connection> connection =
1430 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001431 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001432 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001433 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001434 if (DEBUG_FOCUS) {
1435 ALOGD("Dropping event delivery to target with channel '%s' because it "
1436 "is no longer registered with the input dispatcher.",
1437 inputTarget.inputChannel->getName().c_str());
1438 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001439 }
1440 }
1441}
1442
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001443void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1444 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1445 // If the policy decides to close the app, we will get a channel removal event via
1446 // unregisterInputChannel, and will clean up the connection that way. We are already not
1447 // sending new pointers to the connection when it blocked, but focused events will continue to
1448 // pile up.
1449 ALOGW("Canceling events for %s because it is unresponsive",
1450 connection->inputChannel->getName().c_str());
1451 if (connection->status == Connection::STATUS_NORMAL) {
1452 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1453 "application not responding");
1454 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001455 }
1456}
1457
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001458void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001459 if (DEBUG_FOCUS) {
1460 ALOGD("Resetting ANR timeouts.");
1461 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001462
1463 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001464 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001465 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001466}
1467
Tiger Huang721e26f2018-07-24 22:26:19 +08001468/**
1469 * Get the display id that the given event should go to. If this event specifies a valid display id,
1470 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1471 * Focused display is the display that the user most recently interacted with.
1472 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001473int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001474 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001475 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001476 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001477 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1478 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001479 break;
1480 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001481 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001482 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1483 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001484 break;
1485 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001486 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001487 case EventEntry::Type::CONFIGURATION_CHANGED:
1488 case EventEntry::Type::DEVICE_RESET: {
1489 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001490 return ADISPLAY_ID_NONE;
1491 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001492 }
1493 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1494}
1495
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001496bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1497 const char* focusedWindowName) {
1498 if (mAnrTracker.empty()) {
1499 // already processed all events that we waited for
1500 mKeyIsWaitingForEventsTimeout = std::nullopt;
1501 return false;
1502 }
1503
1504 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1505 // Start the timer
1506 ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
1507 "focus to change",
1508 focusedWindowName);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001509 mKeyIsWaitingForEventsTimeout = currentTime +
1510 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1511 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001512 return true;
1513 }
1514
1515 // We still have pending events, and already started the timer
1516 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1517 return true; // Still waiting
1518 }
1519
1520 // Waited too long, and some connection still hasn't processed all motions
1521 // Just send the key to the focused window
1522 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1523 focusedWindowName);
1524 mKeyIsWaitingForEventsTimeout = std::nullopt;
1525 return false;
1526}
1527
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001528InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1529 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1530 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001531 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001532
Tiger Huang721e26f2018-07-24 22:26:19 +08001533 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001534 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001535 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001536 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1537
Michael Wrightd02c5b62014-02-10 15:10:22 -08001538 // If there is no currently focused window and no focused application
1539 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001540 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1541 ALOGI("Dropping %s event because there is no focused window or focused application in "
1542 "display %" PRId32 ".",
1543 EventEntry::typeToString(entry.type), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001544 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001545 }
1546
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001547 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1548 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1549 // start interacting with another application via touch (app switch). This code can be removed
1550 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1551 // an app is expected to have a focused window.
1552 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1553 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1554 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001555 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1556 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1557 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001558 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001559 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001560 ALOGW("Waiting because no window has focus but %s may eventually add a "
1561 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001562 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001563 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001564 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001565 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1566 // Already raised ANR. Drop the event
1567 ALOGE("Dropping %s event because there is no focused window",
1568 EventEntry::typeToString(entry.type));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001569 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001570 } else {
1571 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001572 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001573 }
1574 }
1575
1576 // we have a valid, non-null focused window
1577 resetNoFocusedWindowTimeoutLocked();
1578
Michael Wrightd02c5b62014-02-10 15:10:22 -08001579 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001580 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001581 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001582 }
1583
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001584 if (focusedWindowHandle->getInfo()->paused) {
1585 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001586 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001587 }
1588
1589 // If the event is a key event, then we must wait for all previous events to
1590 // complete before delivering it because previous events may have the
1591 // side-effect of transferring focus to a different window and we want to
1592 // ensure that the following keys are sent to the new window.
1593 //
1594 // Suppose the user touches a button in a window then immediately presses "A".
1595 // If the button causes a pop-up window to appear then we want to ensure that
1596 // the "A" key is delivered to the new pop-up window. This is because users
1597 // often anticipate pending UI changes when typing on a keyboard.
1598 // To obtain this behavior, we must serialize key events with respect to all
1599 // prior input events.
1600 if (entry.type == EventEntry::Type::KEY) {
1601 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1602 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001603 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001604 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605 }
1606
1607 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001608 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001609 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1610 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001611
1612 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001613 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001614}
1615
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001616/**
1617 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1618 * that are currently unresponsive.
1619 */
1620std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1621 const std::vector<TouchedMonitor>& monitors) const {
1622 std::vector<TouchedMonitor> responsiveMonitors;
1623 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1624 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1625 sp<Connection> connection = getConnectionLocked(
1626 monitor.monitor.inputChannel->getConnectionToken());
1627 if (connection == nullptr) {
1628 ALOGE("Could not find connection for monitor %s",
1629 monitor.monitor.inputChannel->getName().c_str());
1630 return false;
1631 }
1632 if (!connection->responsive) {
1633 ALOGW("Unresponsive monitor %s will not get the new gesture",
1634 connection->inputChannel->getName().c_str());
1635 return false;
1636 }
1637 return true;
1638 });
1639 return responsiveMonitors;
1640}
1641
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001642InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1643 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1644 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001645 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001646 enum InjectionPermission {
1647 INJECTION_PERMISSION_UNKNOWN,
1648 INJECTION_PERMISSION_GRANTED,
1649 INJECTION_PERMISSION_DENIED
1650 };
1651
Michael Wrightd02c5b62014-02-10 15:10:22 -08001652 // For security reasons, we defer updating the touch state until we are sure that
1653 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001654 int32_t displayId = entry.displayId;
1655 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001656 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1657
1658 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001659 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001660 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001661 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1662 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001663
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001664 // Copy current touch state into tempTouchState.
1665 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1666 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001667 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001668 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001669 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1670 mTouchStatesByDisplay.find(displayId);
1671 if (oldStateIt != mTouchStatesByDisplay.end()) {
1672 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001673 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001674 }
1675
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001676 bool isSplit = tempTouchState.split;
1677 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1678 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1679 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001680 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1681 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1682 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1683 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1684 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001685 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001686 bool wrongDevice = false;
1687 if (newGesture) {
1688 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001689 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001690 ALOGI("Dropping event because a pointer for a different device is already down "
1691 "in display %" PRId32,
1692 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001693 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001694 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001695 switchedDevice = false;
1696 wrongDevice = true;
1697 goto Failed;
1698 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001699 tempTouchState.reset();
1700 tempTouchState.down = down;
1701 tempTouchState.deviceId = entry.deviceId;
1702 tempTouchState.source = entry.source;
1703 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001704 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001705 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001706 ALOGI("Dropping move event because a pointer for a different device is already active "
1707 "in display %" PRId32,
1708 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001709 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001710 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001711 switchedDevice = false;
1712 wrongDevice = true;
1713 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001714 }
1715
1716 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1717 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1718
Garfield Tan00f511d2019-06-12 16:55:40 -07001719 int32_t x;
1720 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001721 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001722 // Always dispatch mouse events to cursor position.
1723 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001724 x = int32_t(entry.xCursorPosition);
1725 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001726 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001727 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1728 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001729 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001730 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001731 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001732 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1733 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001734
1735 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001736 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001737 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001738
Michael Wrightd02c5b62014-02-10 15:10:22 -08001739 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001740 if (newTouchedWindowHandle != nullptr &&
1741 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001742 // New window supports splitting, but we should never split mouse events.
1743 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001744 } else if (isSplit) {
1745 // New window does not support splitting but we have already split events.
1746 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001747 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001748 }
1749
1750 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001751 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001752 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001753 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001754 }
1755
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001756 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1757 ALOGI("Not sending touch event to %s because it is paused",
1758 newTouchedWindowHandle->getName().c_str());
1759 newTouchedWindowHandle = nullptr;
1760 }
1761
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001762 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001763 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001764 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1765 if (!isResponsive) {
1766 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001767 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1768 newTouchedWindowHandle = nullptr;
1769 }
1770 }
1771
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001772 // Drop events that can't be trusted due to occlusion
1773 if (newTouchedWindowHandle != nullptr &&
1774 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1775 TouchOcclusionInfo occlusionInfo =
1776 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001777 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001778 if (DEBUG_TOUCH_OCCLUSION) {
1779 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1780 for (const auto& log : occlusionInfo.debugInfo) {
1781 ALOGD("%s", log.c_str());
1782 }
1783 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001784 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
1785 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1786 ALOGW("Dropping untrusted touch event due to %s/%d",
1787 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1788 newTouchedWindowHandle = nullptr;
1789 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001790 }
1791 }
1792
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001793 // Also don't send the new touch event to unresponsive gesture monitors
1794 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1795
Michael Wright3dd60e22019-03-27 22:06:44 +00001796 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1797 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001798 "(%d, %d) in display %" PRId32 ".",
1799 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001800 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001801 goto Failed;
1802 }
1803
1804 if (newTouchedWindowHandle != nullptr) {
1805 // Set target flags.
1806 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1807 if (isSplit) {
1808 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001809 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001810 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1811 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1812 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1813 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1814 }
1815
1816 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07001817 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
1818 newHoverWindowHandle = nullptr;
1819 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001820 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00001821 }
1822
1823 // Update the temporary touch state.
1824 BitSet32 pointerIds;
1825 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001826 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001827 pointerIds.markBit(pointerId);
1828 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001829 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001830 }
1831
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001832 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001833 } else {
1834 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1835
1836 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001837 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001838 if (DEBUG_FOCUS) {
1839 ALOGD("Dropping event because the pointer is not down or we previously "
1840 "dropped the pointer down event in display %" PRId32,
1841 displayId);
1842 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001843 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001844 goto Failed;
1845 }
1846
1847 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001848 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001849 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001850 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1851 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001852
1853 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001854 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07001855 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001856 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1857 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001858 if (DEBUG_FOCUS) {
1859 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1860 oldTouchedWindowHandle->getName().c_str(),
1861 newTouchedWindowHandle->getName().c_str(), displayId);
1862 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001863 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001864 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1865 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1866 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001867
1868 // Make a slippery entrance into the new window.
1869 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1870 isSplit = true;
1871 }
1872
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001873 int32_t targetFlags =
1874 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001875 if (isSplit) {
1876 targetFlags |= InputTarget::FLAG_SPLIT;
1877 }
1878 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1879 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1880 }
1881
1882 BitSet32 pointerIds;
1883 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001884 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001885 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001886 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001887 }
1888 }
1889 }
1890
1891 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07001892 // Let the previous window know that the hover sequence is over, unless we already did it
1893 // when dispatching it as is to newTouchedWindowHandle.
1894 if (mLastHoverWindowHandle != nullptr &&
1895 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
1896 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001897#if DEBUG_HOVER
1898 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001899 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001900#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001901 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1902 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001903 }
1904
Garfield Tandf26e862020-07-01 20:18:19 -07001905 // Let the new window know that the hover sequence is starting, unless we already did it
1906 // when dispatching it as is to newTouchedWindowHandle.
1907 if (newHoverWindowHandle != nullptr &&
1908 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
1909 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001910#if DEBUG_HOVER
1911 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001912 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001913#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001914 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1915 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1916 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001917 }
1918 }
1919
1920 // Check permission to inject into all touched foreground windows and ensure there
1921 // is at least one touched foreground window.
1922 {
1923 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001924 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001925 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1926 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001927 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001928 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001929 injectionPermission = INJECTION_PERMISSION_DENIED;
1930 goto Failed;
1931 }
1932 }
1933 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001934 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00001935 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001936 ALOGI("Dropping event because there is no touched foreground window in display "
1937 "%" PRId32 " or gesture monitor to receive it.",
1938 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001939 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001940 goto Failed;
1941 }
1942
1943 // Permission granted to injection into all touched foreground windows.
1944 injectionPermission = INJECTION_PERMISSION_GRANTED;
1945 }
1946
1947 // Check whether windows listening for outside touches are owned by the same UID. If it is
1948 // set the policy flag that we will not reveal coordinate information to this window.
1949 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1950 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001951 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001952 if (foregroundWindowHandle) {
1953 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001954 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001955 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1956 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1957 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001958 tempTouchState.addOrUpdateWindow(inputWindowHandle,
1959 InputTarget::FLAG_ZERO_COORDS,
1960 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001961 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001962 }
1963 }
1964 }
1965 }
1966
Michael Wrightd02c5b62014-02-10 15:10:22 -08001967 // If this is the first pointer going down and the touched window has a wallpaper
1968 // then also add the touched wallpaper windows so they are locked in for the duration
1969 // of the touch gesture.
1970 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1971 // engine only supports touch events. We would need to add a mechanism similar
1972 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1973 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1974 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001975 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001976 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001977 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001978 getWindowHandlesLocked(displayId);
1979 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001980 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001981 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01001982 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001983 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001984 .addOrUpdateWindow(windowHandle,
1985 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1986 InputTarget::
1987 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1988 InputTarget::FLAG_DISPATCH_AS_IS,
1989 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001990 }
1991 }
1992 }
1993 }
1994
1995 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001996 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001997
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001998 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001999 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002000 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002001 }
2002
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002003 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002004 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002005 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002006 }
2007
Michael Wrightd02c5b62014-02-10 15:10:22 -08002008 // Drop the outside or hover touch windows since we will not care about them
2009 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002010 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002011
2012Failed:
2013 // Check injection permission once and for all.
2014 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002015 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002016 injectionPermission = INJECTION_PERMISSION_GRANTED;
2017 } else {
2018 injectionPermission = INJECTION_PERMISSION_DENIED;
2019 }
2020 }
2021
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002022 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2023 return injectionResult;
2024 }
2025
Michael Wrightd02c5b62014-02-10 15:10:22 -08002026 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002027 if (!wrongDevice) {
2028 if (switchedDevice) {
2029 if (DEBUG_FOCUS) {
2030 ALOGD("Conflicting pointer actions: Switched to a different device.");
2031 }
2032 *outConflictingPointerActions = true;
2033 }
2034
2035 if (isHoverAction) {
2036 // Started hovering, therefore no longer down.
2037 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002038 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002039 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2040 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002041 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002042 *outConflictingPointerActions = true;
2043 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002044 tempTouchState.reset();
2045 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2046 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2047 tempTouchState.deviceId = entry.deviceId;
2048 tempTouchState.source = entry.source;
2049 tempTouchState.displayId = displayId;
2050 }
2051 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2052 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2053 // All pointers up or canceled.
2054 tempTouchState.reset();
2055 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2056 // First pointer went down.
2057 if (oldState && oldState->down) {
2058 if (DEBUG_FOCUS) {
2059 ALOGD("Conflicting pointer actions: Down received while already down.");
2060 }
2061 *outConflictingPointerActions = true;
2062 }
2063 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2064 // One pointer went up.
2065 if (isSplit) {
2066 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2067 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002068
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002069 for (size_t i = 0; i < tempTouchState.windows.size();) {
2070 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2071 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2072 touchedWindow.pointerIds.clearBit(pointerId);
2073 if (touchedWindow.pointerIds.isEmpty()) {
2074 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2075 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002076 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002077 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002078 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002079 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002080 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002081 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002082
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002083 // Save changes unless the action was scroll in which case the temporary touch
2084 // state was only valid for this one action.
2085 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2086 if (tempTouchState.displayId >= 0) {
2087 mTouchStatesByDisplay[displayId] = tempTouchState;
2088 } else {
2089 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002090 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002091 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002092
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002093 // Update hover state.
2094 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002095 }
2096
Michael Wrightd02c5b62014-02-10 15:10:22 -08002097 return injectionResult;
2098}
2099
2100void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002101 int32_t targetFlags, BitSet32 pointerIds,
2102 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002103 std::vector<InputTarget>::iterator it =
2104 std::find_if(inputTargets.begin(), inputTargets.end(),
2105 [&windowHandle](const InputTarget& inputTarget) {
2106 return inputTarget.inputChannel->getConnectionToken() ==
2107 windowHandle->getToken();
2108 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002109
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002110 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002111
2112 if (it == inputTargets.end()) {
2113 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002114 std::shared_ptr<InputChannel> inputChannel =
2115 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002116 if (inputChannel == nullptr) {
2117 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2118 return;
2119 }
2120 inputTarget.inputChannel = inputChannel;
2121 inputTarget.flags = targetFlags;
2122 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2123 inputTargets.push_back(inputTarget);
2124 it = inputTargets.end() - 1;
2125 }
2126
2127 ALOG_ASSERT(it->flags == targetFlags);
2128 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2129
chaviw1ff3d1e2020-07-01 15:53:47 -07002130 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002131}
2132
Michael Wright3dd60e22019-03-27 22:06:44 +00002133void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002134 int32_t displayId, float xOffset,
2135 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002136 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2137 mGlobalMonitorsByDisplay.find(displayId);
2138
2139 if (it != mGlobalMonitorsByDisplay.end()) {
2140 const std::vector<Monitor>& monitors = it->second;
2141 for (const Monitor& monitor : monitors) {
2142 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002143 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002144 }
2145}
2146
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002147void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2148 float yOffset,
2149 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002150 InputTarget target;
2151 target.inputChannel = monitor.inputChannel;
2152 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002153 ui::Transform t;
2154 t.set(xOffset, yOffset);
2155 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002156 inputTargets.push_back(target);
2157}
2158
Michael Wrightd02c5b62014-02-10 15:10:22 -08002159bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002160 const InjectionState* injectionState) {
2161 if (injectionState &&
2162 (windowHandle == nullptr ||
2163 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2164 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002165 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002166 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002167 "owned by uid %d",
2168 injectionState->injectorPid, injectionState->injectorUid,
2169 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002170 } else {
2171 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002172 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002173 }
2174 return false;
2175 }
2176 return true;
2177}
2178
Robert Carrc9bf1d32020-04-13 17:21:08 -07002179/**
2180 * Indicate whether one window handle should be considered as obscuring
2181 * another window handle. We only check a few preconditions. Actually
2182 * checking the bounds is left to the caller.
2183 */
2184static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2185 const sp<InputWindowHandle>& otherHandle) {
2186 // Compare by token so cloned layers aren't counted
2187 if (haveSameToken(windowHandle, otherHandle)) {
2188 return false;
2189 }
2190 auto info = windowHandle->getInfo();
2191 auto otherInfo = otherHandle->getInfo();
2192 if (!otherInfo->visible) {
2193 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002194 } else if (otherInfo->alpha == 0 &&
2195 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2196 // Those act as if they were invisible, so we don't need to flag them.
2197 // We do want to potentially flag touchable windows even if they have 0
2198 // opacity, since they can consume touches and alter the effects of the
2199 // user interaction (eg. apps that rely on
2200 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2201 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2202 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002203 } else if (info->ownerUid == otherInfo->ownerUid) {
2204 // If ownerUid is the same we don't generate occlusion events as there
2205 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002206 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002207 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002208 return false;
2209 } else if (otherInfo->displayId != info->displayId) {
2210 return false;
2211 }
2212 return true;
2213}
2214
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002215/**
2216 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2217 * untrusted, one should check:
2218 *
2219 * 1. If result.hasBlockingOcclusion is true.
2220 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2221 * BLOCK_UNTRUSTED.
2222 *
2223 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2224 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2225 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2226 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2227 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2228 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2229 *
2230 * If neither of those is true, then it means the touch can be allowed.
2231 */
2232InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2233 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002234 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2235 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002236 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2237 TouchOcclusionInfo info;
2238 info.hasBlockingOcclusion = false;
2239 info.obscuringOpacity = 0;
2240 info.obscuringUid = -1;
2241 std::map<int32_t, float> opacityByUid;
2242 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2243 if (windowHandle == otherHandle) {
2244 break; // All future windows are below us. Exit early.
2245 }
2246 const InputWindowInfo* otherInfo = otherHandle->getInfo();
2247 if (canBeObscuredBy(windowHandle, otherHandle) &&
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002248 windowInfo->ownerUid != otherInfo->ownerUid && otherInfo->frameContainsPoint(x, y)) {
2249 if (DEBUG_TOUCH_OCCLUSION) {
2250 info.debugInfo.push_back(
2251 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2252 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002253 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2254 // we perform the checks below to see if the touch can be propagated or not based on the
2255 // window's touch occlusion mode
2256 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2257 info.hasBlockingOcclusion = true;
2258 info.obscuringUid = otherInfo->ownerUid;
2259 info.obscuringPackage = otherInfo->packageName;
2260 break;
2261 }
2262 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2263 uint32_t uid = otherInfo->ownerUid;
2264 float opacity =
2265 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2266 // Given windows A and B:
2267 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2268 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2269 opacityByUid[uid] = opacity;
2270 if (opacity > info.obscuringOpacity) {
2271 info.obscuringOpacity = opacity;
2272 info.obscuringUid = uid;
2273 info.obscuringPackage = otherInfo->packageName;
2274 }
2275 }
2276 }
2277 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002278 if (DEBUG_TOUCH_OCCLUSION) {
2279 info.debugInfo.push_back(
2280 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2281 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002282 return info;
2283}
2284
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002285std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2286 bool isTouchedWindow) const {
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002287 return StringPrintf(INDENT2 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32
2288 ", mode=%s, alpha=%.2f, "
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002289 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2290 "], touchableRegion=%s, window={%s}, applicationInfo=%s, "
2291 "flags={%s}, inputFeatures={%s}, hasToken=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002292 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002293 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002294 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002295 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2296 info->frameTop, info->frameRight, info->frameBottom,
2297 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002298 info->applicationInfo.name.c_str(), info->flags.string().c_str(),
2299 info->inputFeatures.string().c_str(), toString(info->token != nullptr));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002300}
2301
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002302bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2303 if (occlusionInfo.hasBlockingOcclusion) {
2304 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2305 occlusionInfo.obscuringUid);
2306 return false;
2307 }
2308 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2309 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2310 "%.2f, maximum allowed = %.2f)",
2311 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2312 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2313 return false;
2314 }
2315 return true;
2316}
2317
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002318bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2319 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002320 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002321 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002322 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002323 if (windowHandle == otherHandle) {
2324 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002325 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002326 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002327 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002328 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002329 return true;
2330 }
2331 }
2332 return false;
2333}
2334
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002335bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2336 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002337 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002338 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002339 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002340 if (windowHandle == otherHandle) {
2341 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002342 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002343 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002344 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002345 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002346 return true;
2347 }
2348 }
2349 return false;
2350}
2351
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002352std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002353 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002354 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002355 if (applicationHandle != nullptr) {
2356 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002357 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002358 } else {
2359 return applicationHandle->getName();
2360 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002361 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002362 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002363 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002364 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002365 }
2366}
2367
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002368void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002369 if (eventEntry.type == EventEntry::Type::FOCUS) {
2370 // Focus events are passed to apps, but do not represent user activity.
2371 return;
2372 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002373 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002374 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002375 if (focusedWindowHandle != nullptr) {
2376 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002377 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002378#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002379 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002380#endif
2381 return;
2382 }
2383 }
2384
2385 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002386 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002387 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002388 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2389 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002390 return;
2391 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002392
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002393 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002394 eventType = USER_ACTIVITY_EVENT_TOUCH;
2395 }
2396 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002397 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002398 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002399 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2400 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002401 return;
2402 }
2403 eventType = USER_ACTIVITY_EVENT_BUTTON;
2404 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002405 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002406 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002407 case EventEntry::Type::CONFIGURATION_CHANGED:
2408 case EventEntry::Type::DEVICE_RESET: {
2409 LOG_ALWAYS_FATAL("%s events are not user activity",
2410 EventEntry::typeToString(eventEntry.type));
2411 break;
2412 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002413 }
2414
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002415 std::unique_ptr<CommandEntry> commandEntry =
2416 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002417 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002418 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002419 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002420}
2421
2422void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002423 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002424 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002425 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002426 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002427 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002428 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002429 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002430 ATRACE_NAME(message.c_str());
2431 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002432#if DEBUG_DISPATCH_CYCLE
2433 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002434 "globalScaleFactor=%f, pointerIds=0x%x %s",
2435 connection->getInputChannelName().c_str(), inputTarget.flags,
2436 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2437 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002438#endif
2439
2440 // Skip this event if the connection status is not normal.
2441 // We don't want to enqueue additional outbound events if the connection is broken.
2442 if (connection->status != Connection::STATUS_NORMAL) {
2443#if DEBUG_DISPATCH_CYCLE
2444 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002445 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002446#endif
2447 return;
2448 }
2449
2450 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002451 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2452 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2453 "Entry type %s should not have FLAG_SPLIT",
2454 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002455
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002456 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002457 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002458 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002459 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002460 if (!splitMotionEntry) {
2461 return; // split event was dropped
2462 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002463 if (DEBUG_FOCUS) {
2464 ALOGD("channel '%s' ~ Split motion event.",
2465 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002466 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002467 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002468 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2469 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002470 return;
2471 }
2472 }
2473
2474 // Not splitting. Enqueue dispatch entries for the event as is.
2475 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2476}
2477
2478void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002479 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002480 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002481 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002482 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002483 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002484 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002485 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002486 ATRACE_NAME(message.c_str());
2487 }
2488
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002489 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002490
2491 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002492 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002493 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002494 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002495 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002496 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002497 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002498 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002499 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002500 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002501 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002502 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002503 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002504
2505 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002506 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002507 startDispatchCycleLocked(currentTime, connection);
2508 }
2509}
2510
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002511void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002512 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002513 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002514 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002515 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002516 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2517 connection->getInputChannelName().c_str(),
2518 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002519 ATRACE_NAME(message.c_str());
2520 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002521 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002522 if (!(inputTargetFlags & dispatchMode)) {
2523 return;
2524 }
2525 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2526
2527 // This is a new event.
2528 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002529 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002530 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002531
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002532 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2533 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002534 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002535 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002536 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002537 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002538 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002539 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002540 dispatchEntry->resolvedAction = keyEntry.action;
2541 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002542
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002543 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2544 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002545#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002546 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2547 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002548#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002549 return; // skip the inconsistent event
2550 }
2551 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002552 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002553
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002554 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002555 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002556 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2557 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2558 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2559 static_cast<int32_t>(IdGenerator::Source::OTHER);
2560 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002561 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2562 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2563 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2564 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2565 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2566 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2567 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2568 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2569 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2570 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2571 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002572 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002573 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002574 }
2575 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002576 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2577 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002578#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002579 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2580 "event",
2581 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002582#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002583 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2584 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002585
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002586 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002587 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2588 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2589 }
2590 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2591 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2592 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002593
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002594 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2595 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002596#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002597 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2598 "event",
2599 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002600#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002601 return; // skip the inconsistent event
2602 }
2603
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002604 dispatchEntry->resolvedEventId =
2605 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2606 ? mIdGenerator.nextId()
2607 : motionEntry.id;
2608 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2609 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2610 ") to MotionEvent(id=0x%" PRIx32 ").",
2611 motionEntry.id, dispatchEntry->resolvedEventId);
2612 ATRACE_NAME(message.c_str());
2613 }
2614
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002615 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002616 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002617
2618 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002619 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002620 case EventEntry::Type::FOCUS: {
2621 break;
2622 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002623 case EventEntry::Type::CONFIGURATION_CHANGED:
2624 case EventEntry::Type::DEVICE_RESET: {
2625 LOG_ALWAYS_FATAL("%s events should not go to apps",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002626 EventEntry::typeToString(newEntry.type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002627 break;
2628 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002629 }
2630
2631 // Remember that we are waiting for this dispatch to complete.
2632 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002633 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002634 }
2635
2636 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002637 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002638 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002639}
2640
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002641/**
2642 * This function is purely for debugging. It helps us understand where the user interaction
2643 * was taking place. For example, if user is touching launcher, we will see a log that user
2644 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2645 * We will see both launcher and wallpaper in that list.
2646 * Once the interaction with a particular set of connections starts, no new logs will be printed
2647 * until the set of interacted connections changes.
2648 *
2649 * The following items are skipped, to reduce the logspam:
2650 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2651 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2652 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2653 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2654 * Both of those ACTION_UP events would not be logged
2655 * Monitors (both gesture and global): any gesture monitors or global monitors receiving events
2656 * will not be logged. This is omitted to reduce the amount of data printed.
2657 * If you see <none>, it's likely that one of the gesture monitors pilfered the event, and therefore
2658 * gesture monitor is the only connection receiving the remainder of the gesture.
2659 */
2660void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2661 const std::vector<InputTarget>& targets) {
2662 // Skip ACTION_UP events, and all events other than keys and motions
2663 if (entry.type == EventEntry::Type::KEY) {
2664 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2665 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2666 return;
2667 }
2668 } else if (entry.type == EventEntry::Type::MOTION) {
2669 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2670 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2671 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2672 return;
2673 }
2674 } else {
2675 return; // Not a key or a motion
2676 }
2677
2678 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2679 std::vector<sp<Connection>> newConnections;
2680 for (const InputTarget& target : targets) {
2681 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2682 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2683 continue; // Skip windows that receive ACTION_OUTSIDE
2684 }
2685
2686 sp<IBinder> token = target.inputChannel->getConnectionToken();
2687 sp<Connection> connection = getConnectionLocked(token);
2688 if (connection == nullptr || connection->monitor) {
2689 continue; // We only need to keep track of the non-monitor connections.
2690 }
2691 newConnectionTokens.insert(std::move(token));
2692 newConnections.emplace_back(connection);
2693 }
2694 if (newConnectionTokens == mInteractionConnectionTokens) {
2695 return; // no change
2696 }
2697 mInteractionConnectionTokens = newConnectionTokens;
2698
2699 std::string windowList;
2700 for (const sp<Connection>& connection : newConnections) {
2701 windowList += connection->getWindowName() + ", ";
2702 }
2703 std::string message = "Interaction with windows: " + windowList;
2704 if (windowList.empty()) {
2705 message += "<none>";
2706 }
2707 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2708}
2709
chaviwfd6d3512019-03-25 13:23:49 -07002710void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002711 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002712 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002713 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2714 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002715 return;
2716 }
2717
Vishnu Nairad321cd2020-08-20 16:40:21 -07002718 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
2719 if (focusedToken == token) {
2720 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002721 return;
2722 }
2723
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002724 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2725 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002726 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002727 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002728}
2729
2730void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002731 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002732 if (ATRACE_ENABLED()) {
2733 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002734 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002735 ATRACE_NAME(message.c_str());
2736 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002737#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002738 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002739#endif
2740
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002741 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2742 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002743 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002744 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002745 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002746 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002747
2748 // Publish the event.
2749 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002750 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
2751 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002752 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002753 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2754 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002755
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002756 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002757 status = connection->inputPublisher
2758 .publishKeyEvent(dispatchEntry->seq,
2759 dispatchEntry->resolvedEventId, keyEntry.deviceId,
2760 keyEntry.source, keyEntry.displayId,
2761 std::move(hmac), dispatchEntry->resolvedAction,
2762 dispatchEntry->resolvedFlags, keyEntry.keyCode,
2763 keyEntry.scanCode, keyEntry.metaState,
2764 keyEntry.repeatCount, keyEntry.downTime,
2765 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002766 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002767 }
2768
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002769 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002770 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002771
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002772 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002773 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002774
chaviw82357092020-01-28 13:13:06 -08002775 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002776 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002777 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2778 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002779 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002780 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
2781 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002782 // Don't apply window scale here since we don't want scale to affect raw
2783 // coordinates. The scale will be sent back to the client and applied
2784 // later when requesting relative coordinates.
2785 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2786 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002787 }
2788 usingCoords = scaledCoords;
2789 }
2790 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002791 // We don't want the dispatch target to know.
2792 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002793 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002794 scaledCoords[i].clear();
2795 }
2796 usingCoords = scaledCoords;
2797 }
2798 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002799
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002800 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002801
2802 // Publish the motion event.
2803 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002804 .publishMotionEvent(dispatchEntry->seq,
2805 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002806 motionEntry.deviceId, motionEntry.source,
2807 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002808 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002809 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002810 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002811 motionEntry.edgeFlags, motionEntry.metaState,
2812 motionEntry.buttonState,
2813 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07002814 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002815 motionEntry.xPrecision, motionEntry.yPrecision,
2816 motionEntry.xCursorPosition,
2817 motionEntry.yCursorPosition,
2818 motionEntry.downTime, motionEntry.eventTime,
2819 motionEntry.pointerCount,
2820 motionEntry.pointerProperties, usingCoords);
2821 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002822 break;
2823 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002824 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002825 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002826 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002827 focusEntry.id,
2828 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002829 mInTouchMode);
2830 break;
2831 }
2832
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002833 case EventEntry::Type::CONFIGURATION_CHANGED:
2834 case EventEntry::Type::DEVICE_RESET: {
2835 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002836 EventEntry::typeToString(eventEntry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002837 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002838 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002839 }
2840
2841 // Check the result.
2842 if (status) {
2843 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002844 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002845 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002846 "This is unexpected because the wait queue is empty, so the pipe "
2847 "should be empty and we shouldn't have any problems writing an "
2848 "event to it, status=%d",
2849 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002850 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2851 } else {
2852 // Pipe is full and we are waiting for the app to finish process some events
2853 // before sending more events to it.
2854#if DEBUG_DISPATCH_CYCLE
2855 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002856 "waiting for the application to catch up",
2857 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002858#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08002859 }
2860 } else {
2861 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002862 "status=%d",
2863 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002864 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2865 }
2866 return;
2867 }
2868
2869 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002870 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2871 connection->outboundQueue.end(),
2872 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002873 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002874 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002875 if (connection->responsive) {
2876 mAnrTracker.insert(dispatchEntry->timeoutTime,
2877 connection->inputChannel->getConnectionToken());
2878 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002879 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002880 }
2881}
2882
chaviw09c8d2d2020-08-24 15:48:26 -07002883std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
2884 size_t size;
2885 switch (event.type) {
2886 case VerifiedInputEvent::Type::KEY: {
2887 size = sizeof(VerifiedKeyEvent);
2888 break;
2889 }
2890 case VerifiedInputEvent::Type::MOTION: {
2891 size = sizeof(VerifiedMotionEvent);
2892 break;
2893 }
2894 }
2895 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
2896 return mHmacKeyManager.sign(start, size);
2897}
2898
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002899const std::array<uint8_t, 32> InputDispatcher::getSignature(
2900 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
2901 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
2902 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
2903 // Only sign events up and down events as the purely move events
2904 // are tied to their up/down counterparts so signing would be redundant.
2905 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
2906 verifiedEvent.actionMasked = actionMasked;
2907 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07002908 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002909 }
2910 return INVALID_HMAC;
2911}
2912
2913const std::array<uint8_t, 32> InputDispatcher::getSignature(
2914 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
2915 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
2916 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
2917 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07002918 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002919}
2920
Michael Wrightd02c5b62014-02-10 15:10:22 -08002921void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002922 const sp<Connection>& connection, uint32_t seq,
2923 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924#if DEBUG_DISPATCH_CYCLE
2925 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002926 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002927#endif
2928
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002929 if (connection->status == Connection::STATUS_BROKEN ||
2930 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002931 return;
2932 }
2933
2934 // Notify other system components and prepare to start the next dispatch cycle.
2935 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2936}
2937
2938void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002939 const sp<Connection>& connection,
2940 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002941#if DEBUG_DISPATCH_CYCLE
2942 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002943 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002944#endif
2945
2946 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002947 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002948 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002949 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002950 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002951
2952 // The connection appears to be unrecoverably broken.
2953 // Ignore already broken or zombie connections.
2954 if (connection->status == Connection::STATUS_NORMAL) {
2955 connection->status = Connection::STATUS_BROKEN;
2956
2957 if (notify) {
2958 // Notify other system components.
2959 onDispatchCycleBrokenLocked(currentTime, connection);
2960 }
2961 }
2962}
2963
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002964void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2965 while (!queue.empty()) {
2966 DispatchEntry* dispatchEntry = queue.front();
2967 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002968 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002969 }
2970}
2971
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002972void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002973 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002974 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002975 }
2976 delete dispatchEntry;
2977}
2978
2979int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2980 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2981
2982 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002983 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002984
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002985 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002986 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002987 "fd=%d, events=0x%x",
2988 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002989 return 0; // remove the callback
2990 }
2991
2992 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002993 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002994 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2995 if (!(events & ALOOPER_EVENT_INPUT)) {
2996 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002997 "events=0x%x",
2998 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002999 return 1;
3000 }
3001
3002 nsecs_t currentTime = now();
3003 bool gotOne = false;
3004 status_t status;
3005 for (;;) {
3006 uint32_t seq;
3007 bool handled;
3008 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
3009 if (status) {
3010 break;
3011 }
3012 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
3013 gotOne = true;
3014 }
3015 if (gotOne) {
3016 d->runCommandsLockedInterruptible();
3017 if (status == WOULD_BLOCK) {
3018 return 1;
3019 }
3020 }
3021
3022 notify = status != DEAD_OBJECT || !connection->monitor;
3023 if (notify) {
3024 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003025 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003026 }
3027 } else {
3028 // Monitor channels are never explicitly unregistered.
3029 // We do it automatically when the remote endpoint is closed so don't warn
3030 // about them.
arthurhungd352cb32020-04-28 17:09:28 +08003031 const bool stillHaveWindowHandle =
3032 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3033 nullptr;
3034 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003035 if (notify) {
3036 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003037 "events=0x%x",
3038 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003039 }
3040 }
3041
Garfield Tan15601662020-09-22 15:32:38 -07003042 // Remove the channel.
3043 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003044 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003045 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003046}
3047
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003048void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003049 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003050 for (const auto& pair : mConnectionsByFd) {
3051 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003052 }
3053}
3054
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003055void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003056 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003057 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3058 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3059}
3060
3061void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3062 const CancelationOptions& options,
3063 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3064 for (const auto& it : monitorsByDisplay) {
3065 const std::vector<Monitor>& monitors = it.second;
3066 for (const Monitor& monitor : monitors) {
3067 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003068 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003069 }
3070}
3071
Michael Wrightd02c5b62014-02-10 15:10:22 -08003072void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003073 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003074 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003075 if (connection == nullptr) {
3076 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003077 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003078
3079 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003080}
3081
3082void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3083 const sp<Connection>& connection, const CancelationOptions& options) {
3084 if (connection->status == Connection::STATUS_BROKEN) {
3085 return;
3086 }
3087
3088 nsecs_t currentTime = now();
3089
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003090 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003091 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003092
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003093 if (cancelationEvents.empty()) {
3094 return;
3095 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003096#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003097 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3098 "with reality: %s, mode=%d.",
3099 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3100 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003101#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003102
3103 InputTarget target;
3104 sp<InputWindowHandle> windowHandle =
3105 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3106 if (windowHandle != nullptr) {
3107 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003108 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003109 target.globalScaleFactor = windowInfo->globalScaleFactor;
3110 }
3111 target.inputChannel = connection->inputChannel;
3112 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3113
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003114 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003115 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003116 switch (cancelationEventEntry->type) {
3117 case EventEntry::Type::KEY: {
3118 logOutboundKeyDetails("cancel - ",
3119 static_cast<const KeyEntry&>(*cancelationEventEntry));
3120 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003121 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003122 case EventEntry::Type::MOTION: {
3123 logOutboundMotionDetails("cancel - ",
3124 static_cast<const MotionEntry&>(*cancelationEventEntry));
3125 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003126 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003127 case EventEntry::Type::FOCUS: {
3128 LOG_ALWAYS_FATAL("Canceling focus events is not supported");
3129 break;
3130 }
3131 case EventEntry::Type::CONFIGURATION_CHANGED:
3132 case EventEntry::Type::DEVICE_RESET: {
3133 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3134 EventEntry::typeToString(cancelationEventEntry->type));
3135 break;
3136 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003137 }
3138
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003139 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3140 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003141 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003142
3143 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003144}
3145
Svet Ganov5d3bc372020-01-26 23:11:07 -08003146void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3147 const sp<Connection>& connection) {
3148 if (connection->status == Connection::STATUS_BROKEN) {
3149 return;
3150 }
3151
3152 nsecs_t currentTime = now();
3153
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003154 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003155 connection->inputState.synthesizePointerDownEvents(currentTime);
3156
3157 if (downEvents.empty()) {
3158 return;
3159 }
3160
3161#if DEBUG_OUTBOUND_EVENT_DETAILS
3162 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3163 connection->getInputChannelName().c_str(), downEvents.size());
3164#endif
3165
3166 InputTarget target;
3167 sp<InputWindowHandle> windowHandle =
3168 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3169 if (windowHandle != nullptr) {
3170 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003171 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003172 target.globalScaleFactor = windowInfo->globalScaleFactor;
3173 }
3174 target.inputChannel = connection->inputChannel;
3175 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3176
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003177 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003178 switch (downEventEntry->type) {
3179 case EventEntry::Type::MOTION: {
3180 logOutboundMotionDetails("down - ",
3181 static_cast<const MotionEntry&>(*downEventEntry));
3182 break;
3183 }
3184
3185 case EventEntry::Type::KEY:
3186 case EventEntry::Type::FOCUS:
3187 case EventEntry::Type::CONFIGURATION_CHANGED:
3188 case EventEntry::Type::DEVICE_RESET: {
3189 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3190 EventEntry::typeToString(downEventEntry->type));
3191 break;
3192 }
3193 }
3194
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003195 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3196 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003197 }
3198
3199 startDispatchCycleLocked(currentTime, connection);
3200}
3201
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003202std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3203 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003204 ALOG_ASSERT(pointerIds.value != 0);
3205
3206 uint32_t splitPointerIndexMap[MAX_POINTERS];
3207 PointerProperties splitPointerProperties[MAX_POINTERS];
3208 PointerCoords splitPointerCoords[MAX_POINTERS];
3209
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003210 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003211 uint32_t splitPointerCount = 0;
3212
3213 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003214 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003215 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003216 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003217 uint32_t pointerId = uint32_t(pointerProperties.id);
3218 if (pointerIds.hasBit(pointerId)) {
3219 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3220 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3221 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003222 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003223 splitPointerCount += 1;
3224 }
3225 }
3226
3227 if (splitPointerCount != pointerIds.count()) {
3228 // This is bad. We are missing some of the pointers that we expected to deliver.
3229 // Most likely this indicates that we received an ACTION_MOVE events that has
3230 // different pointer ids than we expected based on the previous ACTION_DOWN
3231 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3232 // in this way.
3233 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003234 "we expected there to be %d pointers. This probably means we received "
3235 "a broken sequence of pointer ids from the input device.",
3236 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003237 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003238 }
3239
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003240 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003241 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003242 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3243 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003244 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3245 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003246 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003247 uint32_t pointerId = uint32_t(pointerProperties.id);
3248 if (pointerIds.hasBit(pointerId)) {
3249 if (pointerIds.count() == 1) {
3250 // The first/last pointer went down/up.
3251 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003252 ? AMOTION_EVENT_ACTION_DOWN
3253 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003254 } else {
3255 // A secondary pointer went down/up.
3256 uint32_t splitPointerIndex = 0;
3257 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3258 splitPointerIndex += 1;
3259 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003260 action = maskedAction |
3261 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003262 }
3263 } else {
3264 // An unrelated pointer changed.
3265 action = AMOTION_EVENT_ACTION_MOVE;
3266 }
3267 }
3268
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003269 int32_t newId = mIdGenerator.nextId();
3270 if (ATRACE_ENABLED()) {
3271 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3272 ") to MotionEvent(id=0x%" PRIx32 ").",
3273 originalMotionEntry.id, newId);
3274 ATRACE_NAME(message.c_str());
3275 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003276 std::unique_ptr<MotionEntry> splitMotionEntry =
3277 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3278 originalMotionEntry.deviceId, originalMotionEntry.source,
3279 originalMotionEntry.displayId,
3280 originalMotionEntry.policyFlags, action,
3281 originalMotionEntry.actionButton,
3282 originalMotionEntry.flags, originalMotionEntry.metaState,
3283 originalMotionEntry.buttonState,
3284 originalMotionEntry.classification,
3285 originalMotionEntry.edgeFlags,
3286 originalMotionEntry.xPrecision,
3287 originalMotionEntry.yPrecision,
3288 originalMotionEntry.xCursorPosition,
3289 originalMotionEntry.yCursorPosition,
3290 originalMotionEntry.downTime, splitPointerCount,
3291 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003292
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003293 if (originalMotionEntry.injectionState) {
3294 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003295 splitMotionEntry->injectionState->refCount += 1;
3296 }
3297
3298 return splitMotionEntry;
3299}
3300
3301void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3302#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003303 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003304#endif
3305
3306 bool needWake;
3307 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003308 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003309
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003310 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3311 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3312 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003313 } // release lock
3314
3315 if (needWake) {
3316 mLooper->wake();
3317 }
3318}
3319
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003320/**
3321 * If one of the meta shortcuts is detected, process them here:
3322 * Meta + Backspace -> generate BACK
3323 * Meta + Enter -> generate HOME
3324 * This will potentially overwrite keyCode and metaState.
3325 */
3326void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003327 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003328 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3329 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3330 if (keyCode == AKEYCODE_DEL) {
3331 newKeyCode = AKEYCODE_BACK;
3332 } else if (keyCode == AKEYCODE_ENTER) {
3333 newKeyCode = AKEYCODE_HOME;
3334 }
3335 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003336 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003337 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003338 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003339 keyCode = newKeyCode;
3340 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3341 }
3342 } else if (action == AKEY_EVENT_ACTION_UP) {
3343 // In order to maintain a consistent stream of up and down events, check to see if the key
3344 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3345 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003346 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003347 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003348 auto replacementIt = mReplacedKeys.find(replacement);
3349 if (replacementIt != mReplacedKeys.end()) {
3350 keyCode = replacementIt->second;
3351 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003352 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3353 }
3354 }
3355}
3356
Michael Wrightd02c5b62014-02-10 15:10:22 -08003357void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3358#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003359 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3360 "policyFlags=0x%x, action=0x%x, "
3361 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3362 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3363 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3364 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003365#endif
3366 if (!validateKeyEvent(args->action)) {
3367 return;
3368 }
3369
3370 uint32_t policyFlags = args->policyFlags;
3371 int32_t flags = args->flags;
3372 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003373 // InputDispatcher tracks and generates key repeats on behalf of
3374 // whatever notifies it, so repeatCount should always be set to 0
3375 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003376 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3377 policyFlags |= POLICY_FLAG_VIRTUAL;
3378 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3379 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003380 if (policyFlags & POLICY_FLAG_FUNCTION) {
3381 metaState |= AMETA_FUNCTION_ON;
3382 }
3383
3384 policyFlags |= POLICY_FLAG_TRUSTED;
3385
Michael Wright78f24442014-08-06 15:55:28 -07003386 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003387 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003388
Michael Wrightd02c5b62014-02-10 15:10:22 -08003389 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003390 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003391 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3392 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003393
Michael Wright2b3c3302018-03-02 17:19:13 +00003394 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003395 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003396 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3397 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003398 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003399 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003400
Michael Wrightd02c5b62014-02-10 15:10:22 -08003401 bool needWake;
3402 { // acquire lock
3403 mLock.lock();
3404
3405 if (shouldSendKeyToInputFilterLocked(args)) {
3406 mLock.unlock();
3407
3408 policyFlags |= POLICY_FLAG_FILTERED;
3409 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3410 return; // event was consumed by the filter
3411 }
3412
3413 mLock.lock();
3414 }
3415
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003416 std::unique_ptr<KeyEntry> newEntry =
3417 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3418 args->displayId, policyFlags, args->action, flags,
3419 keyCode, args->scanCode, metaState, repeatCount,
3420 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003421
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003422 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003423 mLock.unlock();
3424 } // release lock
3425
3426 if (needWake) {
3427 mLooper->wake();
3428 }
3429}
3430
3431bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3432 return mInputFilterEnabled;
3433}
3434
3435void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3436#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003437 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3438 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003439 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3440 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003441 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003442 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3443 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3444 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3445 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003446 for (uint32_t i = 0; i < args->pointerCount; i++) {
3447 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003448 "x=%f, y=%f, pressure=%f, size=%f, "
3449 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3450 "orientation=%f",
3451 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3452 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3453 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3454 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3455 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3456 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3457 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3458 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3459 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3460 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003461 }
3462#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003463 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3464 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003465 return;
3466 }
3467
3468 uint32_t policyFlags = args->policyFlags;
3469 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003470
3471 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003472 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003473 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3474 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003475 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003476 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003477
3478 bool needWake;
3479 { // acquire lock
3480 mLock.lock();
3481
3482 if (shouldSendMotionToInputFilterLocked(args)) {
3483 mLock.unlock();
3484
3485 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003486 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003487 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3488 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003489 args->metaState, args->buttonState, args->classification, transform,
3490 args->xPrecision, args->yPrecision, args->xCursorPosition,
3491 args->yCursorPosition, args->downTime, args->eventTime,
3492 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003493
3494 policyFlags |= POLICY_FLAG_FILTERED;
3495 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3496 return; // event was consumed by the filter
3497 }
3498
3499 mLock.lock();
3500 }
3501
3502 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003503 std::unique_ptr<MotionEntry> newEntry =
3504 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3505 args->source, args->displayId, policyFlags,
3506 args->action, args->actionButton, args->flags,
3507 args->metaState, args->buttonState,
3508 args->classification, args->edgeFlags,
3509 args->xPrecision, args->yPrecision,
3510 args->xCursorPosition, args->yCursorPosition,
3511 args->downTime, args->pointerCount,
3512 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003513
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003514 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003515 mLock.unlock();
3516 } // release lock
3517
3518 if (needWake) {
3519 mLooper->wake();
3520 }
3521}
3522
3523bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003524 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003525}
3526
3527void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3528#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003529 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003530 "switchMask=0x%08x",
3531 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003532#endif
3533
3534 uint32_t policyFlags = args->policyFlags;
3535 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003536 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003537}
3538
3539void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3540#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003541 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3542 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003543#endif
3544
3545 bool needWake;
3546 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003547 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003548
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003549 std::unique_ptr<DeviceResetEntry> newEntry =
3550 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3551 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003552 } // release lock
3553
3554 if (needWake) {
3555 mLooper->wake();
3556 }
3557}
3558
Prabir Pradhan7e186182020-11-10 13:56:45 -08003559void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3560#if DEBUG_INBOUND_EVENT_DETAILS
3561 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3562 args->enabled ? "true" : "false");
3563#endif
3564
3565 // TODO(prabirmsp): Implement.
3566}
3567
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003568InputEventInjectionResult InputDispatcher::injectInputEvent(
3569 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3570 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003571#if DEBUG_INBOUND_EVENT_DETAILS
3572 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003573 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3574 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003575#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003576 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003577
3578 policyFlags |= POLICY_FLAG_INJECTED;
3579 if (hasInjectionPermission(injectorPid, injectorUid)) {
3580 policyFlags |= POLICY_FLAG_TRUSTED;
3581 }
3582
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003583 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003584 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003585 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003586 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3587 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003588 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003589 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003590 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003591
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003592 int32_t flags = incomingKey.getFlags();
3593 int32_t keyCode = incomingKey.getKeyCode();
3594 int32_t metaState = incomingKey.getMetaState();
3595 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003596 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003597 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003598 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003599 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3600 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3601 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003602
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003603 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3604 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003605 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003606
3607 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3608 android::base::Timer t;
3609 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3610 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3611 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3612 std::to_string(t.duration().count()).c_str());
3613 }
3614 }
3615
3616 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003617 std::unique_ptr<KeyEntry> injectedEntry =
3618 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3619 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3620 incomingKey.getDisplayId(), policyFlags, action,
3621 flags, keyCode, incomingKey.getScanCode(), metaState,
3622 incomingKey.getRepeatCount(),
3623 incomingKey.getDownTime());
3624 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003625 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003626 }
3627
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003628 case AINPUT_EVENT_TYPE_MOTION: {
3629 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3630 int32_t action = motionEvent->getAction();
3631 size_t pointerCount = motionEvent->getPointerCount();
3632 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3633 int32_t actionButton = motionEvent->getActionButton();
3634 int32_t displayId = motionEvent->getDisplayId();
3635 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003636 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003637 }
3638
3639 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3640 nsecs_t eventTime = motionEvent->getEventTime();
3641 android::base::Timer t;
3642 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3643 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3644 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3645 std::to_string(t.duration().count()).c_str());
3646 }
3647 }
3648
3649 mLock.lock();
3650 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3651 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003652 std::unique_ptr<MotionEntry> injectedEntry =
3653 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3654 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3655 motionEvent->getDisplayId(), policyFlags, action,
3656 actionButton, motionEvent->getFlags(),
3657 motionEvent->getMetaState(),
3658 motionEvent->getButtonState(),
3659 motionEvent->getClassification(),
3660 motionEvent->getEdgeFlags(),
3661 motionEvent->getXPrecision(),
3662 motionEvent->getYPrecision(),
3663 motionEvent->getRawXCursorPosition(),
3664 motionEvent->getRawYCursorPosition(),
3665 motionEvent->getDownTime(),
3666 uint32_t(pointerCount), pointerProperties,
3667 samplePointerCoords, motionEvent->getXOffset(),
3668 motionEvent->getYOffset());
3669 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003670 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3671 sampleEventTimes += 1;
3672 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003673 std::unique_ptr<MotionEntry> nextInjectedEntry =
3674 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3675 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3676 motionEvent->getDisplayId(), policyFlags,
3677 action, actionButton, motionEvent->getFlags(),
3678 motionEvent->getMetaState(),
3679 motionEvent->getButtonState(),
3680 motionEvent->getClassification(),
3681 motionEvent->getEdgeFlags(),
3682 motionEvent->getXPrecision(),
3683 motionEvent->getYPrecision(),
3684 motionEvent->getRawXCursorPosition(),
3685 motionEvent->getRawYCursorPosition(),
3686 motionEvent->getDownTime(),
3687 uint32_t(pointerCount), pointerProperties,
3688 samplePointerCoords,
3689 motionEvent->getXOffset(),
3690 motionEvent->getYOffset());
3691 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003692 }
3693 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003694 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003695
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003696 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003697 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003698 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003699 }
3700
3701 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003702 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003703 injectionState->injectionIsAsync = true;
3704 }
3705
3706 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003707 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003708
3709 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003710 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003711 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003712 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003713 }
3714
3715 mLock.unlock();
3716
3717 if (needWake) {
3718 mLooper->wake();
3719 }
3720
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003721 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003722 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003723 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003724
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003725 if (syncMode == InputEventInjectionSync::NONE) {
3726 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003727 } else {
3728 for (;;) {
3729 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003730 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003731 break;
3732 }
3733
3734 nsecs_t remainingTimeout = endTime - now();
3735 if (remainingTimeout <= 0) {
3736#if DEBUG_INJECTION
3737 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003738 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003739#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003740 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003741 break;
3742 }
3743
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003744 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003745 }
3746
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003747 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3748 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003749 while (injectionState->pendingForegroundDispatches != 0) {
3750#if DEBUG_INJECTION
3751 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003752 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003753#endif
3754 nsecs_t remainingTimeout = endTime - now();
3755 if (remainingTimeout <= 0) {
3756#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003757 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3758 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003759#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003760 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003761 break;
3762 }
3763
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003764 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003765 }
3766 }
3767 }
3768
3769 injectionState->release();
3770 } // release lock
3771
3772#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003773 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003774 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003775#endif
3776
3777 return injectionResult;
3778}
3779
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003780std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05003781 std::array<uint8_t, 32> calculatedHmac;
3782 std::unique_ptr<VerifiedInputEvent> result;
3783 switch (event.getType()) {
3784 case AINPUT_EVENT_TYPE_KEY: {
3785 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
3786 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
3787 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003788 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05003789 break;
3790 }
3791 case AINPUT_EVENT_TYPE_MOTION: {
3792 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
3793 VerifiedMotionEvent verifiedMotionEvent =
3794 verifiedMotionEventFromMotionEvent(motionEvent);
3795 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003796 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05003797 break;
3798 }
3799 default: {
3800 ALOGE("Cannot verify events of type %" PRId32, event.getType());
3801 return nullptr;
3802 }
3803 }
3804 if (calculatedHmac == INVALID_HMAC) {
3805 return nullptr;
3806 }
3807 if (calculatedHmac != event.getHmac()) {
3808 return nullptr;
3809 }
3810 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003811}
3812
Michael Wrightd02c5b62014-02-10 15:10:22 -08003813bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003814 return injectorUid == 0 ||
3815 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003816}
3817
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003818void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003819 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003820 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003821 if (injectionState) {
3822#if DEBUG_INJECTION
3823 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003824 "injectorPid=%d, injectorUid=%d",
3825 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003826#endif
3827
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003828 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003829 // Log the outcome since the injector did not wait for the injection result.
3830 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003831 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003832 ALOGV("Asynchronous input event injection succeeded.");
3833 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003834 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003835 ALOGW("Asynchronous input event injection failed.");
3836 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003837 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003838 ALOGW("Asynchronous input event injection permission denied.");
3839 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003840 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003841 ALOGW("Asynchronous input event injection timed out.");
3842 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003843 case InputEventInjectionResult::PENDING:
3844 ALOGE("Setting result to 'PENDING' for asynchronous injection");
3845 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003846 }
3847 }
3848
3849 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003850 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003851 }
3852}
3853
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003854void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
3855 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003856 if (injectionState) {
3857 injectionState->pendingForegroundDispatches += 1;
3858 }
3859}
3860
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003861void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
3862 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003863 if (injectionState) {
3864 injectionState->pendingForegroundDispatches -= 1;
3865
3866 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003867 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003868 }
3869 }
3870}
3871
Vishnu Nairad321cd2020-08-20 16:40:21 -07003872const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003873 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003874 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
3875 auto it = mWindowHandlesByDisplay.find(displayId);
3876 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08003877}
3878
Michael Wrightd02c5b62014-02-10 15:10:22 -08003879sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003880 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08003881 if (windowHandleToken == nullptr) {
3882 return nullptr;
3883 }
3884
Arthur Hungb92218b2018-08-14 12:00:21 +08003885 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003886 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003887 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003888 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003889 return windowHandle;
3890 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003891 }
3892 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003893 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003894}
3895
Vishnu Nairad321cd2020-08-20 16:40:21 -07003896sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
3897 int displayId) const {
3898 if (windowHandleToken == nullptr) {
3899 return nullptr;
3900 }
3901
3902 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3903 if (windowHandle->getToken() == windowHandleToken) {
3904 return windowHandle;
3905 }
3906 }
3907 return nullptr;
3908}
3909
3910sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
3911 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
3912 return getWindowHandleLocked(focusedToken, displayId);
3913}
3914
Mady Mellor017bcd12020-06-23 19:12:00 +00003915bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
3916 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003917 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00003918 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08003919 if (handle->getId() == windowHandle->getId() &&
3920 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00003921 if (windowHandle->getInfo()->displayId != it.first) {
3922 ALOGE("Found window %s in display %" PRId32
3923 ", but it should belong to display %" PRId32,
3924 windowHandle->getName().c_str(), it.first,
3925 windowHandle->getInfo()->displayId);
3926 }
3927 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08003928 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003929 }
3930 }
3931 return false;
3932}
3933
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05003934bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
3935 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
3936 const bool noInputChannel =
3937 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3938 if (connection != nullptr && noInputChannel) {
3939 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
3940 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
3941 return false;
3942 }
3943
3944 if (connection == nullptr) {
3945 if (!noInputChannel) {
3946 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
3947 }
3948 return false;
3949 }
3950 if (!connection->responsive) {
3951 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
3952 return false;
3953 }
3954 return true;
3955}
3956
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003957std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
3958 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07003959 size_t count = mInputChannelsByToken.count(token);
3960 if (count == 0) {
3961 return nullptr;
3962 }
3963 return mInputChannelsByToken.at(token);
3964}
3965
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003966void InputDispatcher::updateWindowHandlesForDisplayLocked(
3967 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3968 if (inputWindowHandles.empty()) {
3969 // Remove all handles on a display if there are no windows left.
3970 mWindowHandlesByDisplay.erase(displayId);
3971 return;
3972 }
3973
3974 // Since we compare the pointer of input window handles across window updates, we need
3975 // to make sure the handle object for the same window stays unchanged across updates.
3976 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003977 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003978 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003979 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003980 }
3981
3982 std::vector<sp<InputWindowHandle>> newHandles;
3983 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3984 if (!handle->updateInfo()) {
3985 // handle no longer valid
3986 continue;
3987 }
3988
3989 const InputWindowInfo* info = handle->getInfo();
3990 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3991 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3992 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01003993 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3994 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
3995 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003996 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003997 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003998 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07003999 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004000 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004001 }
4002
4003 if (info->displayId != displayId) {
4004 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4005 handle->getName().c_str(), displayId, info->displayId);
4006 continue;
4007 }
4008
Robert Carredd13602020-04-13 17:24:34 -07004009 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4010 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004011 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004012 oldHandle->updateFrom(handle);
4013 newHandles.push_back(oldHandle);
4014 } else {
4015 newHandles.push_back(handle);
4016 }
4017 }
4018
4019 // Insert or replace
4020 mWindowHandlesByDisplay[displayId] = newHandles;
4021}
4022
Arthur Hung72d8dc32020-03-28 00:48:39 +00004023void InputDispatcher::setInputWindows(
4024 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4025 { // acquire lock
4026 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004027 for (const auto& [displayId, handles] : handlesPerDisplay) {
4028 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004029 }
4030 }
4031 // Wake up poll loop since it may need to make new input dispatching choices.
4032 mLooper->wake();
4033}
4034
Arthur Hungb92218b2018-08-14 12:00:21 +08004035/**
4036 * Called from InputManagerService, update window handle list by displayId that can receive input.
4037 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4038 * If set an empty list, remove all handles from the specific display.
4039 * For focused handle, check if need to change and send a cancel event to previous one.
4040 * For removed handle, check if need to send a cancel event if already in touch.
4041 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004042void InputDispatcher::setInputWindowsLocked(
4043 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004044 if (DEBUG_FOCUS) {
4045 std::string windowList;
4046 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4047 windowList += iwh->getName() + " ";
4048 }
4049 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4050 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004051
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004052 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4053 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4054 const bool noInputWindow =
4055 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4056 if (noInputWindow && window->getToken() != nullptr) {
4057 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4058 window->getName().c_str());
4059 window->releaseChannel();
4060 }
4061 }
4062
Arthur Hung72d8dc32020-03-28 00:48:39 +00004063 // Copy old handles for release if they are no longer present.
4064 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004065
Arthur Hung72d8dc32020-03-28 00:48:39 +00004066 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004067
Vishnu Nair958da932020-08-21 17:12:37 -07004068 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4069 if (mLastHoverWindowHandle &&
4070 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4071 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004072 mLastHoverWindowHandle = nullptr;
4073 }
4074
Vishnu Nair958da932020-08-21 17:12:37 -07004075 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4076 if (focusedToken) {
4077 FocusResult result = checkTokenFocusableLocked(focusedToken, displayId);
4078 if (result != FocusResult::OK) {
4079 onFocusChangedLocked(focusedToken, nullptr, displayId, typeToString(result));
4080 }
4081 }
4082
4083 std::optional<FocusRequest> focusRequest =
4084 getOptionalValueByKey(mPendingFocusRequests, displayId);
4085 if (focusRequest) {
4086 // If the window from the pending request is now visible, provide it focus.
4087 FocusResult result = handleFocusRequestLocked(*focusRequest);
4088 if (result != FocusResult::NOT_VISIBLE) {
4089 // Drop the request if we were able to change the focus or we cannot change
4090 // it for another reason.
4091 mPendingFocusRequests.erase(displayId);
4092 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004093 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004094
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004095 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4096 mTouchStatesByDisplay.find(displayId);
4097 if (stateIt != mTouchStatesByDisplay.end()) {
4098 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004099 for (size_t i = 0; i < state.windows.size();) {
4100 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004101 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004102 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004103 ALOGD("Touched window was removed: %s in display %" PRId32,
4104 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004105 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004106 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004107 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4108 if (touchedInputChannel != nullptr) {
4109 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4110 "touched window was removed");
4111 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004112 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004113 state.windows.erase(state.windows.begin() + i);
4114 } else {
4115 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004116 }
4117 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004118 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004119
Arthur Hung72d8dc32020-03-28 00:48:39 +00004120 // Release information for windows that are no longer present.
4121 // This ensures that unused input channels are released promptly.
4122 // Otherwise, they might stick around until the window handle is destroyed
4123 // which might not happen until the next GC.
4124 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004125 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004126 if (DEBUG_FOCUS) {
4127 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004128 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004129 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004130 // To avoid making too many calls into the compat framework, only
4131 // check for window flags when windows are going away.
4132 // TODO(b/157929241) : delete this. This is only needed temporarily
4133 // in order to gather some data about the flag usage
4134 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4135 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4136 oldWindowHandle->getName().c_str());
4137 if (mCompatService != nullptr) {
4138 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4139 oldWindowHandle->getInfo()->ownerUid);
4140 }
4141 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004142 }
chaviw291d88a2019-02-14 10:33:58 -08004143 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004144}
4145
4146void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004147 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004148 if (DEBUG_FOCUS) {
4149 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4150 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4151 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004152 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004153 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004154
Chris Yea209fde2020-07-22 13:54:51 -07004155 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004156 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004157
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004158 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4159 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004160 }
4161
Chris Yea209fde2020-07-22 13:54:51 -07004162 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004163 if (inputApplicationHandle != nullptr) {
4164 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4165 } else {
4166 mFocusedApplicationHandlesByDisplay.erase(displayId);
4167 }
4168
4169 // No matter what the old focused application was, stop waiting on it because it is
4170 // no longer focused.
4171 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004172 } // release lock
4173
4174 // Wake up poll loop since it may need to make new input dispatching choices.
4175 mLooper->wake();
4176}
4177
Tiger Huang721e26f2018-07-24 22:26:19 +08004178/**
4179 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4180 * the display not specified.
4181 *
4182 * We track any unreleased events for each window. If a window loses the ability to receive the
4183 * released event, we will send a cancel event to it. So when the focused display is changed, we
4184 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4185 * display. The display-specified events won't be affected.
4186 */
4187void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004188 if (DEBUG_FOCUS) {
4189 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4190 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004191 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004192 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004193
4194 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004195 sp<IBinder> oldFocusedWindowToken =
4196 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4197 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004198 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004199 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004200 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004201 CancelationOptions
4202 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4203 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004204 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004205 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4206 }
4207 }
4208 mFocusedDisplayId = displayId;
4209
Chris Ye3c2d6f52020-08-09 10:39:48 -07004210 // Find new focused window and validate
Vishnu Nairad321cd2020-08-20 16:40:21 -07004211 sp<IBinder> newFocusedWindowToken =
4212 getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4213 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004214
Vishnu Nairad321cd2020-08-20 16:40:21 -07004215 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004216 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004217 if (!mFocusedWindowTokenByDisplay.empty()) {
4218 ALOGE("But another display has a focused window\n%s",
4219 dumpFocusedWindowsLocked().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004220 }
4221 }
4222 }
4223
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004224 if (DEBUG_FOCUS) {
4225 logDispatchStateLocked();
4226 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004227 } // release lock
4228
4229 // Wake up poll loop since it may need to make new input dispatching choices.
4230 mLooper->wake();
4231}
4232
Michael Wrightd02c5b62014-02-10 15:10:22 -08004233void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004234 if (DEBUG_FOCUS) {
4235 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4236 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004237
4238 bool changed;
4239 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004240 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004241
4242 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4243 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004244 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004245 }
4246
4247 if (mDispatchEnabled && !enabled) {
4248 resetAndDropEverythingLocked("dispatcher is being disabled");
4249 }
4250
4251 mDispatchEnabled = enabled;
4252 mDispatchFrozen = frozen;
4253 changed = true;
4254 } else {
4255 changed = false;
4256 }
4257
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004258 if (DEBUG_FOCUS) {
4259 logDispatchStateLocked();
4260 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004261 } // release lock
4262
4263 if (changed) {
4264 // Wake up poll loop since it may need to make new input dispatching choices.
4265 mLooper->wake();
4266 }
4267}
4268
4269void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004270 if (DEBUG_FOCUS) {
4271 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4272 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004273
4274 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004275 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004276
4277 if (mInputFilterEnabled == enabled) {
4278 return;
4279 }
4280
4281 mInputFilterEnabled = enabled;
4282 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4283 } // release lock
4284
4285 // Wake up poll loop since there might be work to do to drop everything.
4286 mLooper->wake();
4287}
4288
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004289void InputDispatcher::setInTouchMode(bool inTouchMode) {
4290 std::scoped_lock lock(mLock);
4291 mInTouchMode = inTouchMode;
4292}
4293
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004294void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4295 if (opacity < 0 || opacity > 1) {
4296 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4297 return;
4298 }
4299
4300 std::scoped_lock lock(mLock);
4301 mMaximumObscuringOpacityForTouch = opacity;
4302}
4303
4304void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4305 std::scoped_lock lock(mLock);
4306 mBlockUntrustedTouchesMode = mode;
4307}
4308
chaviwfbe5d9c2018-12-26 12:23:37 -08004309bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4310 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004311 if (DEBUG_FOCUS) {
4312 ALOGD("Trivial transfer to same window.");
4313 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004314 return true;
4315 }
4316
Michael Wrightd02c5b62014-02-10 15:10:22 -08004317 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004318 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004319
chaviwfbe5d9c2018-12-26 12:23:37 -08004320 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4321 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004322 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004323 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004324 return false;
4325 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004326 if (DEBUG_FOCUS) {
4327 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4328 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4329 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004330 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004331 if (DEBUG_FOCUS) {
4332 ALOGD("Cannot transfer focus because windows are on different displays.");
4333 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004334 return false;
4335 }
4336
4337 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004338 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4339 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004340 for (size_t i = 0; i < state.windows.size(); i++) {
4341 const TouchedWindow& touchedWindow = state.windows[i];
4342 if (touchedWindow.windowHandle == fromWindowHandle) {
4343 int32_t oldTargetFlags = touchedWindow.targetFlags;
4344 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004345
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004346 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004347
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004348 int32_t newTargetFlags = oldTargetFlags &
4349 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4350 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004351 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004352
Jeff Brownf086ddb2014-02-11 14:28:48 -08004353 found = true;
4354 goto Found;
4355 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004356 }
4357 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004358 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004359
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004360 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004361 if (DEBUG_FOCUS) {
4362 ALOGD("Focus transfer failed because from window did not have focus.");
4363 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004364 return false;
4365 }
4366
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004367 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4368 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004369 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004370 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004371 CancelationOptions
4372 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4373 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004374 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004375 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004376 }
4377
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004378 if (DEBUG_FOCUS) {
4379 logDispatchStateLocked();
4380 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004381 } // release lock
4382
4383 // Wake up poll loop since it may need to make new input dispatching choices.
4384 mLooper->wake();
4385 return true;
4386}
4387
4388void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004389 if (DEBUG_FOCUS) {
4390 ALOGD("Resetting and dropping all events (%s).", reason);
4391 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004392
4393 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4394 synthesizeCancelationEventsForAllConnectionsLocked(options);
4395
4396 resetKeyRepeatLocked();
4397 releasePendingEventLocked();
4398 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004399 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004400
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004401 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004402 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004403 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004404 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004405}
4406
4407void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004408 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004409 dumpDispatchStateLocked(dump);
4410
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004411 std::istringstream stream(dump);
4412 std::string line;
4413
4414 while (std::getline(stream, line, '\n')) {
4415 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004416 }
4417}
4418
Vishnu Nairad321cd2020-08-20 16:40:21 -07004419std::string InputDispatcher::dumpFocusedWindowsLocked() {
4420 if (mFocusedWindowTokenByDisplay.empty()) {
4421 return INDENT "FocusedWindows: <none>\n";
4422 }
4423
4424 std::string dump;
4425 dump += INDENT "FocusedWindows:\n";
4426 for (auto& it : mFocusedWindowTokenByDisplay) {
4427 const int32_t displayId = it.first;
4428 const sp<InputWindowHandle> windowHandle = getFocusedWindowHandleLocked(displayId);
4429 if (windowHandle) {
4430 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
4431 windowHandle->getName().c_str());
4432 } else {
4433 dump += StringPrintf(INDENT2 "displayId=%" PRId32
4434 " has focused token without a window'\n",
4435 displayId);
4436 }
4437 }
4438 return dump;
4439}
4440
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004441std::string InputDispatcher::dumpPendingFocusRequestsLocked() {
4442 if (mPendingFocusRequests.empty()) {
4443 return INDENT "mPendingFocusRequests: <none>\n";
4444 }
4445
4446 std::string dump;
4447 dump += INDENT "mPendingFocusRequests:\n";
4448 for (const auto& [displayId, focusRequest] : mPendingFocusRequests) {
4449 // Rather than printing raw values for focusRequest.token and focusRequest.focusedToken,
4450 // try to resolve them to actual windows.
4451 std::string windowName = getConnectionNameLocked(focusRequest.token);
4452 std::string focusedWindowName = getConnectionNameLocked(focusRequest.focusedToken);
4453 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", token->%s, focusedToken->%s\n",
4454 displayId, windowName.c_str(), focusedWindowName.c_str());
4455 }
4456 return dump;
4457}
4458
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004459void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004460 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4461 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4462 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004463 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004464
Tiger Huang721e26f2018-07-24 22:26:19 +08004465 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4466 dump += StringPrintf(INDENT "FocusedApplications:\n");
4467 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4468 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004469 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004470 const std::chrono::duration timeout =
4471 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004472 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004473 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004474 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004475 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004476 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004477 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004478 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004479
Vishnu Nairad321cd2020-08-20 16:40:21 -07004480 dump += dumpFocusedWindowsLocked();
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004481 dump += dumpPendingFocusRequestsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004482
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004483 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004484 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004485 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4486 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004487 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004488 state.displayId, toString(state.down), toString(state.split),
4489 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004490 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004491 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004492 for (size_t i = 0; i < state.windows.size(); i++) {
4493 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004494 dump += StringPrintf(INDENT4
4495 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4496 i, touchedWindow.windowHandle->getName().c_str(),
4497 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004498 }
4499 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004500 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004501 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004502 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004503 dump += INDENT3 "Portal windows:\n";
4504 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004505 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004506 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4507 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004508 }
4509 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004510 }
4511 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004512 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004513 }
4514
Arthur Hungb92218b2018-08-14 12:00:21 +08004515 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004516 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004517 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004518 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004519 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004520 dump += INDENT2 "Windows:\n";
4521 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004522 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004523 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004524
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004525 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004526 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004527 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004528 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004529 "frame=[%d,%d][%d,%d], globalScale=%f, "
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004530 "applicationInfo=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004531 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004532 i, windowInfo->name.c_str(), windowInfo->id,
4533 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004534 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004535 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004536 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004537 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004538 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004539 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004540 windowInfo->frameLeft, windowInfo->frameTop,
4541 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004542 windowInfo->globalScaleFactor,
4543 windowInfo->applicationInfo.name.c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004544 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004545 dump += StringPrintf(", inputFeatures=%s",
4546 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004547 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004548 "ms, trustedOverlay=%s, hasToken=%s, "
4549 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004550 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004551 millis(windowInfo->dispatchingTimeout),
4552 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004553 toString(windowInfo->token != nullptr),
4554 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004555 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004556 }
4557 } else {
4558 dump += INDENT2 "Windows: <none>\n";
4559 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004560 }
4561 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004562 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004563 }
4564
Michael Wright3dd60e22019-03-27 22:06:44 +00004565 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004566 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004567 const std::vector<Monitor>& monitors = it.second;
4568 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4569 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004570 }
4571 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004572 const std::vector<Monitor>& monitors = it.second;
4573 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4574 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004575 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004576 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004577 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004578 }
4579
4580 nsecs_t currentTime = now();
4581
4582 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004583 if (!mRecentQueue.empty()) {
4584 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004585 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004586 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004587 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004588 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004589 }
4590 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004591 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004592 }
4593
4594 // Dump event currently being dispatched.
4595 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004596 dump += INDENT "PendingEvent:\n";
4597 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004598 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004599 dump += StringPrintf(", age=%" PRId64 "ms\n",
4600 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004601 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004602 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004603 }
4604
4605 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004606 if (!mInboundQueue.empty()) {
4607 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004608 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004609 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004610 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004611 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004612 }
4613 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004614 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004615 }
4616
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004617 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004618 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004619 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4620 const KeyReplacement& replacement = pair.first;
4621 int32_t newKeyCode = pair.second;
4622 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004623 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004624 }
4625 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004626 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004627 }
4628
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004629 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004630 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004631 for (const auto& pair : mConnectionsByFd) {
4632 const sp<Connection>& connection = pair.second;
4633 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004634 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004635 pair.first, connection->getInputChannelName().c_str(),
4636 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004637 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004638
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004639 if (!connection->outboundQueue.empty()) {
4640 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4641 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004642 dump += dumpQueue(connection->outboundQueue, currentTime);
4643
Michael Wrightd02c5b62014-02-10 15:10:22 -08004644 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004645 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004646 }
4647
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004648 if (!connection->waitQueue.empty()) {
4649 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4650 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004651 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004652 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004653 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004654 }
4655 }
4656 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004657 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004658 }
4659
4660 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004661 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4662 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004663 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004664 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004665 }
4666
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004667 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004668 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4669 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4670 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004671}
4672
Michael Wright3dd60e22019-03-27 22:06:44 +00004673void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4674 const size_t numMonitors = monitors.size();
4675 for (size_t i = 0; i < numMonitors; i++) {
4676 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004677 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004678 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4679 dump += "\n";
4680 }
4681}
4682
Garfield Tan15601662020-09-22 15:32:38 -07004683base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4684 const std::string& name) {
4685#if DEBUG_CHANNEL_CREATION
4686 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004687#endif
4688
Garfield Tan15601662020-09-22 15:32:38 -07004689 std::shared_ptr<InputChannel> serverChannel;
4690 std::unique_ptr<InputChannel> clientChannel;
4691 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4692
4693 if (result) {
4694 return base::Error(result) << "Failed to open input channel pair with name " << name;
4695 }
4696
Michael Wrightd02c5b62014-02-10 15:10:22 -08004697 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004698 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004699 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004700
Garfield Tan15601662020-09-22 15:32:38 -07004701 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004702 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004703 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004704
Michael Wrightd02c5b62014-02-10 15:10:22 -08004705 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4706 } // release lock
4707
4708 // Wake the looper because some connections have changed.
4709 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004710 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004711}
4712
Garfield Tan15601662020-09-22 15:32:38 -07004713base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
4714 int32_t displayId, bool isGestureMonitor, const std::string& name) {
4715 std::shared_ptr<InputChannel> serverChannel;
4716 std::unique_ptr<InputChannel> clientChannel;
4717 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4718 if (result) {
4719 return base::Error(result) << "Failed to open input channel pair with name " << name;
4720 }
4721
Michael Wright3dd60e22019-03-27 22:06:44 +00004722 { // acquire lock
4723 std::scoped_lock _l(mLock);
4724
4725 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004726 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4727 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004728 }
4729
Garfield Tan15601662020-09-22 15:32:38 -07004730 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004731
Garfield Tan15601662020-09-22 15:32:38 -07004732 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004733 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004734 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004735
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004736 auto& monitorsByDisplay =
4737 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Garfield Tan15601662020-09-22 15:32:38 -07004738 monitorsByDisplay[displayId].emplace_back(serverChannel);
Michael Wright3dd60e22019-03-27 22:06:44 +00004739
4740 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004741 }
Garfield Tan15601662020-09-22 15:32:38 -07004742
Michael Wright3dd60e22019-03-27 22:06:44 +00004743 // Wake the looper because some connections have changed.
4744 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004745 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004746}
4747
Garfield Tan15601662020-09-22 15:32:38 -07004748status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004749 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004750 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004751
Garfield Tan15601662020-09-22 15:32:38 -07004752 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004753 if (status) {
4754 return status;
4755 }
4756 } // release lock
4757
4758 // Wake the poll loop because removing the connection may have changed the current
4759 // synchronization state.
4760 mLooper->wake();
4761 return OK;
4762}
4763
Garfield Tan15601662020-09-22 15:32:38 -07004764status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
4765 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004766 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004767 if (connection == nullptr) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004768 ALOGW("Attempted to unregister already unregistered input channel");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004769 return BAD_VALUE;
4770 }
4771
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004772 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004773 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07004774
Michael Wrightd02c5b62014-02-10 15:10:22 -08004775 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004776 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004777 }
4778
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004779 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004780
4781 nsecs_t currentTime = now();
4782 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4783
4784 connection->status = Connection::STATUS_ZOMBIE;
4785 return OK;
4786}
4787
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004788void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
4789 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
4790 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00004791}
4792
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004793void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004794 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00004795 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004796 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004797 std::vector<Monitor>& monitors = it->second;
4798 const size_t numMonitors = monitors.size();
4799 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004800 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004801 monitors.erase(monitors.begin() + i);
4802 break;
4803 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004804 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004805 if (monitors.empty()) {
4806 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004807 } else {
4808 ++it;
4809 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004810 }
4811}
4812
Michael Wright3dd60e22019-03-27 22:06:44 +00004813status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4814 { // acquire lock
4815 std::scoped_lock _l(mLock);
4816 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4817
4818 if (!foundDisplayId) {
4819 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4820 return BAD_VALUE;
4821 }
4822 int32_t displayId = foundDisplayId.value();
4823
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004824 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4825 mTouchStatesByDisplay.find(displayId);
4826 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004827 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4828 return BAD_VALUE;
4829 }
4830
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004831 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00004832 std::optional<int32_t> foundDeviceId;
4833 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004834 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004835 foundDeviceId = state.deviceId;
4836 }
4837 }
4838 if (!foundDeviceId || !state.down) {
4839 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004840 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004841 return BAD_VALUE;
4842 }
4843 int32_t deviceId = foundDeviceId.value();
4844
4845 // Send cancel events to all the input channels we're stealing from.
4846 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004847 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004848 options.deviceId = deviceId;
4849 options.displayId = displayId;
4850 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004851 std::shared_ptr<InputChannel> channel =
4852 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004853 if (channel != nullptr) {
4854 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4855 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004856 }
4857 // Then clear the current touch state so we stop dispatching to them as well.
4858 state.filterNonMonitors();
4859 }
4860 return OK;
4861}
4862
Michael Wright3dd60e22019-03-27 22:06:44 +00004863std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4864 const sp<IBinder>& token) {
4865 for (const auto& it : mGestureMonitorsByDisplay) {
4866 const std::vector<Monitor>& monitors = it.second;
4867 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004868 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004869 return it.first;
4870 }
4871 }
4872 }
4873 return std::nullopt;
4874}
4875
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004876sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004877 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004878 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004879 }
4880
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004881 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004882 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004883 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004884 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004885 }
4886 }
Robert Carr4e670e52018-08-15 13:26:12 -07004887
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004888 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004889}
4890
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004891std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
4892 sp<Connection> connection = getConnectionLocked(connectionToken);
4893 if (connection == nullptr) {
4894 return "<nullptr>";
4895 }
4896 return connection->getInputChannelName();
4897}
4898
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004899void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004900 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004901 removeByValue(mConnectionsByFd, connection);
4902}
4903
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004904void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4905 const sp<Connection>& connection, uint32_t seq,
4906 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004907 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4908 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004909 commandEntry->connection = connection;
4910 commandEntry->eventTime = currentTime;
4911 commandEntry->seq = seq;
4912 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004913 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004914}
4915
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004916void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4917 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004918 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004919 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004920
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004921 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4922 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004923 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004924 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925}
4926
Vishnu Nairad321cd2020-08-20 16:40:21 -07004927void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
4928 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004929 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4930 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004931 commandEntry->oldToken = oldToken;
4932 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004933 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004934}
4935
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004936void InputDispatcher::onAnrLocked(const Connection& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004937 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
4938 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004939 if (connection.waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004940 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004941 connection.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004942 return;
4943 }
4944 /**
4945 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
4946 * may not be the one that caused the timeout to occur. One possibility is that window timeout
4947 * has changed. This could cause newer entries to time out before the already dispatched
4948 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
4949 * processes the events linearly. So providing information about the oldest entry seems to be
4950 * most useful.
4951 */
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004952 DispatchEntry* oldestEntry = *connection.waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004953 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
4954 std::string reason =
4955 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004956 connection.inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004957 ns2ms(currentWait),
4958 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06004959 sp<IBinder> connectionToken = connection.inputChannel->getConnectionToken();
4960 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004961
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05004962 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4963 &InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible);
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06004964 commandEntry->connectionToken = connectionToken;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004965 commandEntry->reason = std::move(reason);
4966 postCommandLocked(std::move(commandEntry));
4967}
4968
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05004969void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
4970 std::string reason =
4971 StringPrintf("%s does not have a focused window", application->getName().c_str());
4972 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004973
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05004974 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4975 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
4976 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004977 postCommandLocked(std::move(commandEntry));
4978}
4979
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00004980void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
4981 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4982 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
4983 commandEntry->obscuringPackage = obscuringPackage;
4984 postCommandLocked(std::move(commandEntry));
4985}
4986
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004987void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
4988 const std::string& reason) {
4989 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
4990 updateLastAnrStateLocked(windowLabel, reason);
4991}
4992
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05004993void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
4994 const std::string& reason) {
4995 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004996 updateLastAnrStateLocked(windowLabel, reason);
4997}
4998
4999void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5000 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005001 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005002 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005003 struct tm tm;
5004 localtime_r(&t, &tm);
5005 char timestr[64];
5006 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005007 mLastAnrState.clear();
5008 mLastAnrState += INDENT "ANR:\n";
5009 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005010 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5011 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005012 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005013}
5014
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005015void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005016 mLock.unlock();
5017
5018 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5019
5020 mLock.lock();
5021}
5022
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005023void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005024 sp<Connection> connection = commandEntry->connection;
5025
5026 if (connection->status != Connection::STATUS_ZOMBIE) {
5027 mLock.unlock();
5028
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005029 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005030
5031 mLock.lock();
5032 }
5033}
5034
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005035void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005036 sp<IBinder> oldToken = commandEntry->oldToken;
5037 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005038 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005039 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005040 mLock.lock();
5041}
5042
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005043void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005044 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005045
5046 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5047
5048 mLock.lock();
5049}
5050
5051void InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible(
5052 CommandEntry* commandEntry) {
5053 mLock.unlock();
5054
5055 mPolicy->notifyConnectionUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005056
5057 mLock.lock();
5058
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005059 // stop waking up for events in this connection, it is already not responding
5060 sp<Connection> connection = getConnectionLocked(commandEntry->connectionToken);
5061 if (connection == nullptr) {
5062 return;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005063 }
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005064 cancelEventsForAnrLocked(connection);
5065}
5066
5067void InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5068 mLock.unlock();
5069
5070 mPolicy->notifyConnectionResponsive(commandEntry->connectionToken);
5071
5072 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005073}
5074
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005075void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5076 mLock.unlock();
5077
5078 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5079
5080 mLock.lock();
5081}
5082
Michael Wrightd02c5b62014-02-10 15:10:22 -08005083void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5084 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005085 KeyEntry& entry = *(commandEntry->keyEntry);
5086 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005087
5088 mLock.unlock();
5089
Michael Wright2b3c3302018-03-02 17:19:13 +00005090 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005091 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005092 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005093 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5094 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005095 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005096 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005097
5098 mLock.lock();
5099
5100 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005101 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005102 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005103 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005104 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005105 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5106 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005107 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005108}
5109
chaviwfd6d3512019-03-25 13:23:49 -07005110void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5111 mLock.unlock();
5112 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5113 mLock.lock();
5114}
5115
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005116/**
5117 * Connection is responsive if it has no events in the waitQueue that are older than the
5118 * current time.
5119 */
5120static bool isConnectionResponsive(const Connection& connection) {
5121 const nsecs_t currentTime = now();
5122 for (const DispatchEntry* entry : connection.waitQueue) {
5123 if (entry->timeoutTime < currentTime) {
5124 return false;
5125 }
5126 }
5127 return true;
5128}
5129
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005130void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005131 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005132 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005133 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005134 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005135
5136 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005137 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005138 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005139 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005140 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005141 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005142 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005143 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005144 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5145 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005146 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005147 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005148
5149 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005150 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005151 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005152 restartEvent =
5153 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005154 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005155 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005156 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5157 handled);
5158 } else {
5159 restartEvent = false;
5160 }
5161
5162 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005163 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005164 // contents of the wait queue to have been drained, so we need to double-check
5165 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005166 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5167 if (dispatchEntryIt != connection->waitQueue.end()) {
5168 dispatchEntry = *dispatchEntryIt;
5169 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005170 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5171 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005172 if (!connection->responsive) {
5173 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005174 if (connection->responsive) {
5175 // The connection was unresponsive, and now it's responsive. Tell the policy
5176 // about it so that it can stop ANR.
5177 std::unique_ptr<CommandEntry> connectionResponsiveCommand =
5178 std::make_unique<CommandEntry>(
5179 &InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible);
5180 connectionResponsiveCommand->connectionToken = connectionToken;
5181 postCommandLocked(std::move(connectionResponsiveCommand));
5182 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005183 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005184 traceWaitQueueLength(connection);
5185 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005186 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005187 traceOutboundQueueLength(connection);
5188 } else {
5189 releaseDispatchEntry(dispatchEntry);
5190 }
5191 }
5192
5193 // Start the next dispatch cycle for this connection.
5194 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005195}
5196
5197bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005198 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005199 KeyEntry& keyEntry, bool handled) {
5200 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005201 if (!handled) {
5202 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005203 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005204 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005205 return false;
5206 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005207
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005208 // Get the fallback key state.
5209 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005210 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005211 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005212 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005213 connection->inputState.removeFallbackKey(originalKeyCode);
5214 }
5215
5216 if (handled || !dispatchEntry->hasForegroundTarget()) {
5217 // If the application handles the original key for which we previously
5218 // generated a fallback or if the window is not a foreground window,
5219 // then cancel the associated fallback key, if any.
5220 if (fallbackKeyCode != -1) {
5221 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005222#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005223 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005224 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005225 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005226#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005227 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005228 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005229
5230 mLock.unlock();
5231
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005232 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005233 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005234
5235 mLock.lock();
5236
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005237 // Cancel the fallback key.
5238 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005239 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005240 "application handled the original non-fallback key "
5241 "or is no longer a foreground target, "
5242 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005243 options.keyCode = fallbackKeyCode;
5244 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005245 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005246 connection->inputState.removeFallbackKey(originalKeyCode);
5247 }
5248 } else {
5249 // If the application did not handle a non-fallback key, first check
5250 // that we are in a good state to perform unhandled key event processing
5251 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005252 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005253 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005254#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005255 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005256 "since this is not an initial down. "
5257 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005258 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005259#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005260 return false;
5261 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005262
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005263 // Dispatch the unhandled key to the policy.
5264#if DEBUG_OUTBOUND_EVENT_DETAILS
5265 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005266 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005267 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005268#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005269 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005270
5271 mLock.unlock();
5272
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005273 bool fallback =
5274 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005275 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005276
5277 mLock.lock();
5278
5279 if (connection->status != Connection::STATUS_NORMAL) {
5280 connection->inputState.removeFallbackKey(originalKeyCode);
5281 return false;
5282 }
5283
5284 // Latch the fallback keycode for this key on an initial down.
5285 // The fallback keycode cannot change at any other point in the lifecycle.
5286 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005287 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005288 fallbackKeyCode = event.getKeyCode();
5289 } else {
5290 fallbackKeyCode = AKEYCODE_UNKNOWN;
5291 }
5292 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5293 }
5294
5295 ALOG_ASSERT(fallbackKeyCode != -1);
5296
5297 // Cancel the fallback key if the policy decides not to send it anymore.
5298 // We will continue to dispatch the key to the policy but we will no
5299 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005300 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5301 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005302#if DEBUG_OUTBOUND_EVENT_DETAILS
5303 if (fallback) {
5304 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005305 "as a fallback for %d, but on the DOWN it had requested "
5306 "to send %d instead. Fallback canceled.",
5307 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005308 } else {
5309 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005310 "but on the DOWN it had requested to send %d. "
5311 "Fallback canceled.",
5312 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005313 }
5314#endif
5315
5316 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5317 "canceling fallback, policy no longer desires it");
5318 options.keyCode = fallbackKeyCode;
5319 synthesizeCancelationEventsForConnectionLocked(connection, options);
5320
5321 fallback = false;
5322 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005323 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005324 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005325 }
5326 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005327
5328#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005329 {
5330 std::string msg;
5331 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5332 connection->inputState.getFallbackKeys();
5333 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005334 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005335 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005336 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005337 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005338 }
5339#endif
5340
5341 if (fallback) {
5342 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005343 keyEntry.eventTime = event.getEventTime();
5344 keyEntry.deviceId = event.getDeviceId();
5345 keyEntry.source = event.getSource();
5346 keyEntry.displayId = event.getDisplayId();
5347 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5348 keyEntry.keyCode = fallbackKeyCode;
5349 keyEntry.scanCode = event.getScanCode();
5350 keyEntry.metaState = event.getMetaState();
5351 keyEntry.repeatCount = event.getRepeatCount();
5352 keyEntry.downTime = event.getDownTime();
5353 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005354
5355#if DEBUG_OUTBOUND_EVENT_DETAILS
5356 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005357 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005358 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005359#endif
5360 return true; // restart the event
5361 } else {
5362#if DEBUG_OUTBOUND_EVENT_DETAILS
5363 ALOGD("Unhandled key event: No fallback key.");
5364#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005365
5366 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005367 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005368 }
5369 }
5370 return false;
5371}
5372
5373bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005374 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005375 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005376 return false;
5377}
5378
5379void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5380 mLock.unlock();
5381
5382 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5383
5384 mLock.lock();
5385}
5386
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005387KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
5388 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08005389 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08005390 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
5391 entry.repeatCount, entry.downTime, entry.eventTime);
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005392 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005393}
5394
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005395void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5396 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005397 // TODO Write some statistics about how long we spend waiting.
5398}
5399
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005400/**
5401 * Report the touch event latency to the statsd server.
5402 * Input events are reported for statistics if:
5403 * - This is a touchscreen event
5404 * - InputFilter is not enabled
5405 * - Event is not injected or synthesized
5406 *
5407 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5408 * from getting aggregated with the "old" data.
5409 */
5410void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5411 REQUIRES(mLock) {
5412 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5413 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5414 if (!reportForStatistics) {
5415 return;
5416 }
5417
5418 if (mTouchStatistics.shouldReport()) {
5419 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5420 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5421 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5422 mTouchStatistics.reset();
5423 }
5424 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5425 mTouchStatistics.addValue(latencyMicros);
5426}
5427
Michael Wrightd02c5b62014-02-10 15:10:22 -08005428void InputDispatcher::traceInboundQueueLengthLocked() {
5429 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005430 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005431 }
5432}
5433
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005434void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005435 if (ATRACE_ENABLED()) {
5436 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005437 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005438 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005439 }
5440}
5441
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005442void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005443 if (ATRACE_ENABLED()) {
5444 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005445 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005446 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005447 }
5448}
5449
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005450void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005451 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005452
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005453 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005454 dumpDispatchStateLocked(dump);
5455
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005456 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005457 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005458 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005459 }
5460}
5461
5462void InputDispatcher::monitor() {
5463 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005464 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005465 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005466 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005467}
5468
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005469/**
5470 * Wake up the dispatcher and wait until it processes all events and commands.
5471 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5472 * this method can be safely called from any thread, as long as you've ensured that
5473 * the work you are interested in completing has already been queued.
5474 */
5475bool InputDispatcher::waitForIdle() {
5476 /**
5477 * Timeout should represent the longest possible time that a device might spend processing
5478 * events and commands.
5479 */
5480 constexpr std::chrono::duration TIMEOUT = 100ms;
5481 std::unique_lock lock(mLock);
5482 mLooper->wake();
5483 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5484 return result == std::cv_status::no_timeout;
5485}
5486
Vishnu Naire798b472020-07-23 13:52:21 -07005487/**
5488 * Sets focus to the window identified by the token. This must be called
5489 * after updating any input window handles.
5490 *
5491 * Params:
5492 * request.token - input channel token used to identify the window that should gain focus.
5493 * request.focusedToken - the token that the caller expects currently to be focused. If the
5494 * specified token does not match the currently focused window, this request will be dropped.
5495 * If the specified focused token matches the currently focused window, the call will succeed.
5496 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5497 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5498 * when requesting the focus change. This determines which request gets
5499 * precedence if there is a focus change request from another source such as pointer down.
5500 */
Vishnu Nair958da932020-08-21 17:12:37 -07005501void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5502 { // acquire lock
5503 std::scoped_lock _l(mLock);
5504
5505 const int32_t displayId = request.displayId;
5506 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5507 if (request.focusedToken && oldFocusedToken != request.focusedToken) {
5508 ALOGD_IF(DEBUG_FOCUS,
5509 "setFocusedWindow on display %" PRId32
5510 " ignored, reason: focusedToken is not focused",
5511 displayId);
5512 return;
5513 }
5514
5515 mPendingFocusRequests.erase(displayId);
5516 FocusResult result = handleFocusRequestLocked(request);
5517 if (result == FocusResult::NOT_VISIBLE) {
5518 // The requested window is not currently visible. Wait for the window to become visible
5519 // and then provide it focus. This is to handle situations where a user action triggers
5520 // a new window to appear. We want to be able to queue any key events after the user
5521 // action and deliver it to the newly focused window. In order for this to happen, we
5522 // take focus from the currently focused window so key events can be queued.
5523 ALOGD_IF(DEBUG_FOCUS,
5524 "setFocusedWindow on display %" PRId32
5525 " pending, reason: window is not visible",
5526 displayId);
5527 mPendingFocusRequests[displayId] = request;
5528 onFocusChangedLocked(oldFocusedToken, nullptr, displayId,
5529 "setFocusedWindow_AwaitingWindowVisibility");
5530 } else if (result != FocusResult::OK) {
5531 ALOGW("setFocusedWindow on display %" PRId32 " ignored, reason:%s", displayId,
5532 typeToString(result));
5533 }
5534 } // release lock
5535 // Wake up poll loop since it may need to make new input dispatching choices.
5536 mLooper->wake();
5537}
5538
5539InputDispatcher::FocusResult InputDispatcher::handleFocusRequestLocked(
5540 const FocusRequest& request) {
5541 const int32_t displayId = request.displayId;
5542 const sp<IBinder> newFocusedToken = request.token;
5543 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5544
5545 if (oldFocusedToken == request.token) {
5546 ALOGD_IF(DEBUG_FOCUS,
5547 "setFocusedWindow on display %" PRId32 " ignored, reason: already focused",
5548 displayId);
5549 return FocusResult::OK;
5550 }
5551
5552 FocusResult result = checkTokenFocusableLocked(newFocusedToken, displayId);
5553 if (result != FocusResult::OK) {
5554 return result;
5555 }
5556
5557 std::string_view reason =
5558 (request.focusedToken) ? "setFocusedWindow_FocusCheck" : "setFocusedWindow";
5559 onFocusChangedLocked(oldFocusedToken, newFocusedToken, displayId, reason);
5560 return FocusResult::OK;
5561}
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005562
Vishnu Nairad321cd2020-08-20 16:40:21 -07005563void InputDispatcher::onFocusChangedLocked(const sp<IBinder>& oldFocusedToken,
5564 const sp<IBinder>& newFocusedToken, int32_t displayId,
5565 std::string_view reason) {
5566 if (oldFocusedToken) {
5567 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(oldFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005568 if (focusedInputChannel) {
5569 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5570 "focus left window");
5571 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005572 enqueueFocusEventLocked(oldFocusedToken, false /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005573 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005574 mFocusedWindowTokenByDisplay.erase(displayId);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005575 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005576 if (newFocusedToken) {
5577 mFocusedWindowTokenByDisplay[displayId] = newFocusedToken;
5578 enqueueFocusEventLocked(newFocusedToken, true /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005579 }
5580
5581 if (mFocusedDisplayId == displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005582 notifyFocusChangedLocked(oldFocusedToken, newFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005583 }
5584}
Vishnu Nair958da932020-08-21 17:12:37 -07005585
5586/**
5587 * Checks if the window token can be focused on a display. The token can be focused if there is
5588 * at least one window handle that is visible with the same token and all window handles with the
5589 * same token are focusable.
5590 *
5591 * In the case of mirroring, two windows may share the same window token and their visibility
5592 * might be different. Example, the mirrored window can cover the window its mirroring. However,
5593 * we expect the focusability of the windows to match since its hard to reason why one window can
5594 * receive focus events and the other cannot when both are backed by the same input channel.
5595 */
5596InputDispatcher::FocusResult InputDispatcher::checkTokenFocusableLocked(const sp<IBinder>& token,
5597 int32_t displayId) const {
5598 bool allWindowsAreFocusable = true;
5599 bool visibleWindowFound = false;
5600 bool windowFound = false;
5601 for (const sp<InputWindowHandle>& window : getWindowHandlesLocked(displayId)) {
5602 if (window->getToken() != token) {
5603 continue;
5604 }
5605 windowFound = true;
5606 if (window->getInfo()->visible) {
5607 // Check if at least a single window is visible.
5608 visibleWindowFound = true;
5609 }
5610 if (!window->getInfo()->focusable) {
5611 // Check if all windows with the window token are focusable.
5612 allWindowsAreFocusable = false;
5613 break;
5614 }
5615 }
5616
5617 if (!windowFound) {
5618 return FocusResult::NO_WINDOW;
5619 }
5620 if (!allWindowsAreFocusable) {
5621 return FocusResult::NOT_FOCUSABLE;
5622 }
5623 if (!visibleWindowFound) {
5624 return FocusResult::NOT_VISIBLE;
5625 }
5626
5627 return FocusResult::OK;
5628}
Garfield Tane84e6f92019-08-29 17:28:41 -07005629} // namespace android::inputdispatcher