blob: 6c44a54550a05c67281948cc3be931f0295056df [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
Garfield Tan15601662020-09-22 15:32:38 -070031// Log debug messages about channel creation
32#define DEBUG_CHANNEL_CREATION 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080033
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
Siarhei Vishniakou86587282019-09-09 18:20:15 +010038static constexpr bool DEBUG_FOCUS = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -080039
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +000040// Log debug messages about touch occlusion
41// STOPSHIP(b/169067926): Set to false
42static constexpr bool DEBUG_TOUCH_OCCLUSION = true;
43
Michael Wrightd02c5b62014-02-10 15:10:22 -080044// Log debug messages about the app switch latency optimization.
45#define DEBUG_APP_SWITCH 0
46
47// Log debug messages about hover events.
48#define DEBUG_HOVER 0
49
50#include "InputDispatcher.h"
51
Michael Wright2b3c3302018-03-02 17:19:13 +000052#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080053#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050054#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070055#include <binder/Binder.h>
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100056#include <binder/IServiceManager.h>
57#include <com/android/internal/compat/IPlatformCompatNative.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080058#include <input/InputDevice.h>
Michael Wright44753b12020-07-08 13:48:11 +010059#include <input/InputWindow.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070060#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000061#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070062#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010063#include <statslog.h>
64#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070065#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080066
Michael Wright44753b12020-07-08 13:48:11 +010067#include <cerrno>
68#include <cinttypes>
69#include <climits>
70#include <cstddef>
71#include <ctime>
72#include <queue>
73#include <sstream>
74
75#include "Connection.h"
76
Michael Wrightd02c5b62014-02-10 15:10:22 -080077#define INDENT " "
78#define INDENT2 " "
79#define INDENT3 " "
80#define INDENT4 " "
81
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080082using android::base::StringPrintf;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080083using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100084using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080085using android::os::InputEventInjectionResult;
86using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100087using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080088
Garfield Tane84e6f92019-08-29 17:28:41 -070089namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080090
91// Default input dispatching timeout if there is no focused application or paused window
92// from which to determine an appropriate dispatching timeout.
Siarhei Vishniakou70622952020-07-30 11:17:23 -050093constexpr std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT =
94 std::chrono::milliseconds(android::os::IInputConstants::DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
Michael Wrightd02c5b62014-02-10 15:10:22 -080095
96// Amount of time to allow for all pending events to be processed when an app switch
97// key is on the way. This is used to preempt input dispatch and drop input events
98// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000099constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800100
101// Amount of time to allow for an event to be dispatched (measured since its eventTime)
102// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000103constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104
Michael Wrightd02c5b62014-02-10 15:10:22 -0800105// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +0000106constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
107
108// Log a warning when an interception call takes longer than this to process.
109constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800110
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700111// Additional key latency in case a connection is still processing some motion events.
112// This will help with the case when a user touched a button that opens a new window,
113// and gives us the chance to dispatch the key to this new window.
114constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
115
Michael Wrightd02c5b62014-02-10 15:10:22 -0800116// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000117constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
118
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000119// Event log tags. See EventLogTags.logtags for reference
120constexpr int LOGTAG_INPUT_INTERACTION = 62000;
121constexpr int LOGTAG_INPUT_FOCUS = 62001;
122
Michael Wrightd02c5b62014-02-10 15:10:22 -0800123static inline nsecs_t now() {
124 return systemTime(SYSTEM_TIME_MONOTONIC);
125}
126
127static inline const char* toString(bool value) {
128 return value ? "true" : "false";
129}
130
131static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700132 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
133 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800134}
135
136static bool isValidKeyAction(int32_t action) {
137 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700138 case AKEY_EVENT_ACTION_DOWN:
139 case AKEY_EVENT_ACTION_UP:
140 return true;
141 default:
142 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800143 }
144}
145
146static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700147 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800148 ALOGE("Key event has invalid action code 0x%x", action);
149 return false;
150 }
151 return true;
152}
153
Michael Wright7b159c92015-05-14 14:48:03 +0100154static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800155 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700156 case AMOTION_EVENT_ACTION_DOWN:
157 case AMOTION_EVENT_ACTION_UP:
158 case AMOTION_EVENT_ACTION_CANCEL:
159 case AMOTION_EVENT_ACTION_MOVE:
160 case AMOTION_EVENT_ACTION_OUTSIDE:
161 case AMOTION_EVENT_ACTION_HOVER_ENTER:
162 case AMOTION_EVENT_ACTION_HOVER_MOVE:
163 case AMOTION_EVENT_ACTION_HOVER_EXIT:
164 case AMOTION_EVENT_ACTION_SCROLL:
165 return true;
166 case AMOTION_EVENT_ACTION_POINTER_DOWN:
167 case AMOTION_EVENT_ACTION_POINTER_UP: {
168 int32_t index = getMotionEventActionPointerIndex(action);
169 return index >= 0 && index < pointerCount;
170 }
171 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
172 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
173 return actionButton != 0;
174 default:
175 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800176 }
177}
178
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500179static int64_t millis(std::chrono::nanoseconds t) {
180 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
181}
182
Michael Wright7b159c92015-05-14 14:48:03 +0100183static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700184 const PointerProperties* pointerProperties) {
185 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186 ALOGE("Motion event has invalid action code 0x%x", action);
187 return false;
188 }
189 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000190 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700191 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800192 return false;
193 }
194 BitSet32 pointerIdBits;
195 for (size_t i = 0; i < pointerCount; i++) {
196 int32_t id = pointerProperties[i].id;
197 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700198 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
199 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800200 return false;
201 }
202 if (pointerIdBits.hasBit(id)) {
203 ALOGE("Motion event has duplicate pointer id %d", id);
204 return false;
205 }
206 pointerIdBits.markBit(id);
207 }
208 return true;
209}
210
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000211static std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800212 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000213 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214 }
215
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000216 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217 bool first = true;
218 Region::const_iterator cur = region.begin();
219 Region::const_iterator const tail = region.end();
220 while (cur != tail) {
221 if (first) {
222 first = false;
223 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800224 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800225 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800226 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800227 cur++;
228 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000229 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800230}
231
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500232static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
233 constexpr size_t maxEntries = 50; // max events to print
234 constexpr size_t skipBegin = maxEntries / 2;
235 const size_t skipEnd = queue.size() - maxEntries / 2;
236 // skip from maxEntries / 2 ... size() - maxEntries/2
237 // only print from 0 .. skipBegin and then from skipEnd .. size()
238
239 std::string dump;
240 for (size_t i = 0; i < queue.size(); i++) {
241 const DispatchEntry& entry = *queue[i];
242 if (i >= skipBegin && i < skipEnd) {
243 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
244 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
245 continue;
246 }
247 dump.append(INDENT4);
248 dump += entry.eventEntry->getDescription();
249 dump += StringPrintf(", seq=%" PRIu32
250 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
251 entry.seq, entry.targetFlags, entry.resolvedAction,
252 ns2ms(currentTime - entry.eventEntry->eventTime));
253 if (entry.deliveryTime != 0) {
254 // This entry was delivered, so add information on how long we've been waiting
255 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
256 }
257 dump.append("\n");
258 }
259 return dump;
260}
261
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700262/**
263 * Find the entry in std::unordered_map by key, and return it.
264 * If the entry is not found, return a default constructed entry.
265 *
266 * Useful when the entries are vectors, since an empty vector will be returned
267 * if the entry is not found.
268 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
269 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700270template <typename K, typename V>
271static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700272 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700273 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800274}
275
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700276/**
277 * Find the entry in std::unordered_map by value, and remove it.
278 * If more than one entry has the same value, then all matching
279 * key-value pairs will be removed.
280 *
281 * Return true if at least one value has been removed.
282 */
283template <typename K, typename V>
284static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
285 bool removed = false;
286 for (auto it = map.begin(); it != map.end();) {
287 if (it->second == value) {
288 it = map.erase(it);
289 removed = true;
290 } else {
291 it++;
292 }
293 }
294 return removed;
295}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800296
Vishnu Nair958da932020-08-21 17:12:37 -0700297/**
298 * Find the entry in std::unordered_map by key and return the value as an optional.
299 */
300template <typename K, typename V>
301static std::optional<V> getOptionalValueByKey(const std::unordered_map<K, V>& map, K key) {
302 auto it = map.find(key);
303 return it != map.end() ? std::optional<V>{it->second} : std::nullopt;
304}
305
chaviwaf87b3e2019-10-01 16:59:28 -0700306static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
307 if (first == second) {
308 return true;
309 }
310
311 if (first == nullptr || second == nullptr) {
312 return false;
313 }
314
315 return first->getToken() == second->getToken();
316}
317
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800318static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
319 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
320}
321
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000322static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700323 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000324 int32_t inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700325 if (inputTarget.useDefaultPointerTransform()) {
326 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700327 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
chaviw1ff3d1e2020-07-01 15:53:47 -0700328 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000329 }
330
331 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
332 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
333
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700334 std::vector<PointerCoords> pointerCoords;
335 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000336
337 // Use the first pointer information to normalize all other pointers. This could be any pointer
338 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700339 // uses the transform for the normalized pointer.
340 const ui::Transform& firstPointerTransform =
341 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
342 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000343
344 // Iterate through all pointers in the event to normalize against the first.
345 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
346 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
347 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700348 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000349
350 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700351 // First, apply the current pointer's transform to update the coordinates into
352 // window space.
353 pointerCoords[pointerIndex].transform(currTransform);
354 // Next, apply the inverse transform of the normalized coordinates so the
355 // current coordinates are transformed into the normalized coordinate space.
356 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000357 }
358
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700359 std::unique_ptr<MotionEntry> combinedMotionEntry =
360 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
361 motionEntry.deviceId, motionEntry.source,
362 motionEntry.displayId, motionEntry.policyFlags,
363 motionEntry.action, motionEntry.actionButton,
364 motionEntry.flags, motionEntry.metaState,
365 motionEntry.buttonState, motionEntry.classification,
366 motionEntry.edgeFlags, motionEntry.xPrecision,
367 motionEntry.yPrecision, motionEntry.xCursorPosition,
368 motionEntry.yCursorPosition, motionEntry.downTime,
369 motionEntry.pointerCount, motionEntry.pointerProperties,
370 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000371
372 if (motionEntry.injectionState) {
373 combinedMotionEntry->injectionState = motionEntry.injectionState;
374 combinedMotionEntry->injectionState->refCount += 1;
375 }
376
377 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700378 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
379 firstPointerTransform, inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000380 return dispatchEntry;
381}
382
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700383static void addGestureMonitors(const std::vector<Monitor>& monitors,
384 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
385 float yOffset = 0) {
386 if (monitors.empty()) {
387 return;
388 }
389 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
390 for (const Monitor& monitor : monitors) {
391 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
392 }
393}
394
Garfield Tan15601662020-09-22 15:32:38 -0700395static status_t openInputChannelPair(const std::string& name,
396 std::shared_ptr<InputChannel>& serverChannel,
397 std::unique_ptr<InputChannel>& clientChannel) {
398 std::unique_ptr<InputChannel> uniqueServerChannel;
399 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
400
401 serverChannel = std::move(uniqueServerChannel);
402 return result;
403}
404
Vishnu Nair958da932020-08-21 17:12:37 -0700405const char* InputDispatcher::typeToString(InputDispatcher::FocusResult result) {
406 switch (result) {
407 case InputDispatcher::FocusResult::OK:
408 return "Ok";
409 case InputDispatcher::FocusResult::NO_WINDOW:
410 return "Window not found";
411 case InputDispatcher::FocusResult::NOT_FOCUSABLE:
412 return "Window not focusable";
413 case InputDispatcher::FocusResult::NOT_VISIBLE:
414 return "Window not visible";
415 }
416}
417
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500418template <typename T>
419static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
420 if (lhs == nullptr && rhs == nullptr) {
421 return true;
422 }
423 if (lhs == nullptr || rhs == nullptr) {
424 return false;
425 }
426 return *lhs == *rhs;
427}
428
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000429static sp<IPlatformCompatNative> getCompatService() {
430 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
431 if (service == nullptr) {
432 ALOGE("Failed to link to compat service");
433 return nullptr;
434 }
435 return interface_cast<IPlatformCompatNative>(service);
436}
437
Michael Wrightd02c5b62014-02-10 15:10:22 -0800438// --- InputDispatcher ---
439
Garfield Tan00f511d2019-06-12 16:55:40 -0700440InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
441 : mPolicy(policy),
442 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700443 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800444 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700445 mAppSwitchSawKeyDown(false),
446 mAppSwitchDueTime(LONG_LONG_MAX),
447 mNextUnblockedEvent(nullptr),
448 mDispatchEnabled(false),
449 mDispatchFrozen(false),
450 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800451 // mInTouchMode will be initialized by the WindowManager to the default device config.
452 // To avoid leaking stack in case that call never comes, and for tests,
453 // initialize it here anyways.
454 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100455 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000456 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800457 mFocusedWindowRequestedPointerCapture(false),
458 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000459 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800460 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800461 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800462
Yi Kong9b14ac62018-07-17 13:48:38 -0700463 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800464
465 policy->getDispatcherConfiguration(&mConfig);
466}
467
468InputDispatcher::~InputDispatcher() {
469 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800470 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800471
472 resetKeyRepeatLocked();
473 releasePendingEventLocked();
474 drainInboundQueueLocked();
475 }
476
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700477 while (!mConnectionsByFd.empty()) {
478 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700479 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800480 }
481}
482
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700483status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700484 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700485 return ALREADY_EXISTS;
486 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700487 mThread = std::make_unique<InputThread>(
488 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
489 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700490}
491
492status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700493 if (mThread && mThread->isCallingThread()) {
494 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700495 return INVALID_OPERATION;
496 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700497 mThread.reset();
498 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700499}
500
Michael Wrightd02c5b62014-02-10 15:10:22 -0800501void InputDispatcher::dispatchOnce() {
502 nsecs_t nextWakeupTime = LONG_LONG_MAX;
503 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800504 std::scoped_lock _l(mLock);
505 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800506
507 // Run a dispatch loop if there are no pending commands.
508 // The dispatch loop might enqueue commands to run afterwards.
509 if (!haveCommandsLocked()) {
510 dispatchOnceInnerLocked(&nextWakeupTime);
511 }
512
513 // Run all pending commands if there are any.
514 // If any commands were run then force the next poll to wake up immediately.
515 if (runCommandsLockedInterruptible()) {
516 nextWakeupTime = LONG_LONG_MIN;
517 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800518
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700519 // If we are still waiting for ack on some events,
520 // we might have to wake up earlier to check if an app is anr'ing.
521 const nsecs_t nextAnrCheck = processAnrsLocked();
522 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
523
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800524 // We are about to enter an infinitely long sleep, because we have no commands or
525 // pending or queued events
526 if (nextWakeupTime == LONG_LONG_MAX) {
527 mDispatcherEnteredIdle.notify_all();
528 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800529 } // release lock
530
531 // Wait for callback or timeout or wake. (make sure we round up, not down)
532 nsecs_t currentTime = now();
533 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
534 mLooper->pollOnce(timeoutMillis);
535}
536
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700537/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500538 * Raise ANR if there is no focused window.
539 * Before the ANR is raised, do a final state check:
540 * 1. The currently focused application must be the same one we are waiting for.
541 * 2. Ensure we still don't have a focused window.
542 */
543void InputDispatcher::processNoFocusedWindowAnrLocked() {
544 // Check if the application that we are waiting for is still focused.
545 std::shared_ptr<InputApplicationHandle> focusedApplication =
546 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
547 if (focusedApplication == nullptr ||
548 focusedApplication->getApplicationToken() !=
549 mAwaitedFocusedApplication->getApplicationToken()) {
550 // Unexpected because we should have reset the ANR timer when focused application changed
551 ALOGE("Waited for a focused window, but focused application has already changed to %s",
552 focusedApplication->getName().c_str());
553 return; // The focused application has changed.
554 }
555
556 const sp<InputWindowHandle>& focusedWindowHandle =
557 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
558 if (focusedWindowHandle != nullptr) {
559 return; // We now have a focused window. No need for ANR.
560 }
561 onAnrLocked(mAwaitedFocusedApplication);
562}
563
564/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700565 * Check if any of the connections' wait queues have events that are too old.
566 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
567 * Return the time at which we should wake up next.
568 */
569nsecs_t InputDispatcher::processAnrsLocked() {
570 const nsecs_t currentTime = now();
571 nsecs_t nextAnrCheck = LONG_LONG_MAX;
572 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
573 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
574 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500575 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700576 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500577 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700578 return LONG_LONG_MIN;
579 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500580 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700581 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
582 }
583 }
584
585 // Check if any connection ANRs are due
586 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
587 if (currentTime < nextAnrCheck) { // most likely scenario
588 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
589 }
590
591 // If we reached here, we have an unresponsive connection.
592 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
593 if (connection == nullptr) {
594 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
595 return nextAnrCheck;
596 }
597 connection->responsive = false;
598 // Stop waking up for this unresponsive connection
599 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -0500600 onAnrLocked(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700601 return LONG_LONG_MIN;
602}
603
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500604std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700605 sp<InputWindowHandle> window = getWindowHandleLocked(token);
606 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500607 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700608 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500609 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700610}
611
Michael Wrightd02c5b62014-02-10 15:10:22 -0800612void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
613 nsecs_t currentTime = now();
614
Jeff Browndc5992e2014-04-11 01:27:26 -0700615 // Reset the key repeat timer whenever normal dispatch is suspended while the
616 // device is in a non-interactive state. This is to ensure that we abort a key
617 // repeat if the device is just coming out of sleep.
618 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800619 resetKeyRepeatLocked();
620 }
621
622 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
623 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100624 if (DEBUG_FOCUS) {
625 ALOGD("Dispatch frozen. Waiting some more.");
626 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800627 return;
628 }
629
630 // Optimize latency of app switches.
631 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
632 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
633 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
634 if (mAppSwitchDueTime < *nextWakeupTime) {
635 *nextWakeupTime = mAppSwitchDueTime;
636 }
637
638 // Ready to start a new event.
639 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700640 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700641 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800642 if (isAppSwitchDue) {
643 // The inbound queue is empty so the app switch key we were waiting
644 // for will never arrive. Stop waiting for it.
645 resetPendingAppSwitchLocked(false);
646 isAppSwitchDue = false;
647 }
648
649 // Synthesize a key repeat if appropriate.
650 if (mKeyRepeatState.lastKeyEntry) {
651 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
652 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
653 } else {
654 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
655 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
656 }
657 }
658 }
659
660 // Nothing to do if there is no pending event.
661 if (!mPendingEvent) {
662 return;
663 }
664 } else {
665 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700666 mPendingEvent = mInboundQueue.front();
667 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800668 traceInboundQueueLengthLocked();
669 }
670
671 // Poke user activity for this event.
672 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700673 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800674 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800675 }
676
677 // Now we have an event to dispatch.
678 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700679 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800680 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700681 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800682 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700683 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800684 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700685 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800686 }
687
688 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700689 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800690 }
691
692 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700693 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700694 const ConfigurationChangedEntry& typedEntry =
695 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700696 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700697 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700698 break;
699 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800700
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700701 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700702 const DeviceResetEntry& typedEntry =
703 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700704 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700705 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700706 break;
707 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800708
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100709 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700710 std::shared_ptr<FocusEntry> typedEntry =
711 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100712 dispatchFocusLocked(currentTime, typedEntry);
713 done = true;
714 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
715 break;
716 }
717
Prabir Pradhan99987712020-11-10 18:43:05 -0800718 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
719 const auto typedEntry =
720 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
721 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
722 done = true;
723 break;
724 }
725
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700726 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700727 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700728 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700729 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700730 resetPendingAppSwitchLocked(true);
731 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700732 } else if (dropReason == DropReason::NOT_DROPPED) {
733 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700734 }
735 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700736 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700737 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700738 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700739 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
740 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700741 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700742 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700743 break;
744 }
745
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700746 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700747 std::shared_ptr<MotionEntry> motionEntry =
748 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700749 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
750 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800751 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700752 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700753 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700754 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700755 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
756 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700757 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700758 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700759 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800760 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800761 }
762
763 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700764 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700765 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800766 }
Michael Wright3a981722015-06-10 15:26:13 +0100767 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800768
769 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700770 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800771 }
772}
773
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700774/**
775 * Return true if the events preceding this incoming motion event should be dropped
776 * Return false otherwise (the default behaviour)
777 */
778bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700779 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700780 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700781
782 // Optimize case where the current application is unresponsive and the user
783 // decides to touch a window in a different application.
784 // If the application takes too long to catch up then we drop all events preceding
785 // the touch into the other window.
786 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700787 int32_t displayId = motionEntry.displayId;
788 int32_t x = static_cast<int32_t>(
789 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
790 int32_t y = static_cast<int32_t>(
791 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
792 sp<InputWindowHandle> touchedWindowHandle =
793 findTouchedWindowAtLocked(displayId, x, y, nullptr);
794 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700795 touchedWindowHandle->getApplicationToken() !=
796 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700797 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700798 ALOGI("Pruning input queue because user touched a different application while waiting "
799 "for %s",
800 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700801 return true;
802 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700803
804 // Alternatively, maybe there's a gesture monitor that could handle this event
805 std::vector<TouchedMonitor> gestureMonitors =
806 findTouchedGestureMonitorsLocked(displayId, {});
807 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
808 sp<Connection> connection =
809 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000810 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700811 // This monitor could take more input. Drop all events preceding this
812 // event, so that gesture monitor could get a chance to receive the stream
813 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
814 "responsive gesture monitor that may handle the event",
815 mAwaitedFocusedApplication->getName().c_str());
816 return true;
817 }
818 }
819 }
820
821 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
822 // yet been processed by some connections, the dispatcher will wait for these motion
823 // events to be processed before dispatching the key event. This is because these motion events
824 // may cause a new window to be launched, which the user might expect to receive focus.
825 // To prevent waiting forever for such events, just send the key to the currently focused window
826 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
827 ALOGD("Received a new pointer down event, stop waiting for events to process and "
828 "just send the pending key event to the focused window.");
829 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700830 }
831 return false;
832}
833
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700834bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700835 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700836 mInboundQueue.push_back(std::move(newEntry));
837 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800838 traceInboundQueueLengthLocked();
839
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700840 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700841 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700842 // Optimize app switch latency.
843 // If the application takes too long to catch up then we drop all events preceding
844 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700845 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700846 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700847 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700848 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700849 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700850 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800851#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700852 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800853#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700854 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700855 mAppSwitchSawKeyDown = false;
856 needWake = true;
857 }
858 }
859 }
860 break;
861 }
862
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700863 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700864 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
865 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700866 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800867 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700868 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800869 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100870 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700871 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
872 break;
873 }
874 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -0800875 case EventEntry::Type::DEVICE_RESET:
876 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700877 // nothing to do
878 break;
879 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800880 }
881
882 return needWake;
883}
884
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700885void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700886 mRecentQueue.push_back(entry);
887 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700888 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800889 }
890}
891
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700892sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700893 int32_t y, TouchState* touchState,
894 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700895 bool addPortalWindows) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700896 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
897 LOG_ALWAYS_FATAL(
898 "Must provide a valid touch state if adding portal windows or outside targets");
899 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800900 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700901 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800902 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800903 const InputWindowInfo* windowInfo = windowHandle->getInfo();
904 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100905 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800906
907 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100908 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
909 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
910 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800911 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800912 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700913 if (portalToDisplayId != ADISPLAY_ID_NONE &&
914 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800915 if (addPortalWindows) {
916 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700917 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800918 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700919 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700920 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800921 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800922 // Found window.
923 return windowHandle;
924 }
925 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800926
Michael Wright44753b12020-07-08 13:48:11 +0100927 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700928 touchState->addOrUpdateWindow(windowHandle,
929 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
930 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800931 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800932 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800933 }
934 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700935 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800936}
937
Garfield Tane84e6f92019-08-29 17:28:41 -0700938std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700939 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000940 std::vector<TouchedMonitor> touchedMonitors;
941
942 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
943 addGestureMonitors(monitors, touchedMonitors);
944 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
945 const InputWindowInfo* windowInfo = portalWindow->getInfo();
946 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700947 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
948 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000949 }
950 return touchedMonitors;
951}
952
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700953void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800954 const char* reason;
955 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700956 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800957#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700958 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800959#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700960 reason = "inbound event was dropped because the policy consumed it";
961 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700962 case DropReason::DISABLED:
963 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700964 ALOGI("Dropped event because input dispatch is disabled.");
965 }
966 reason = "inbound event was dropped because input dispatch is disabled";
967 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700968 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700969 ALOGI("Dropped event because of pending overdue app switch.");
970 reason = "inbound event was dropped because of pending overdue app switch";
971 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700972 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700973 ALOGI("Dropped event because the current application is not responding and the user "
974 "has started interacting with a different application.");
975 reason = "inbound event was dropped because the current application is not responding "
976 "and the user has started interacting with a different application";
977 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700978 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700979 ALOGI("Dropped event because it is stale.");
980 reason = "inbound event was dropped because it is stale";
981 break;
Prabir Pradhan99987712020-11-10 18:43:05 -0800982 case DropReason::NO_POINTER_CAPTURE:
983 ALOGI("Dropped event because there is no window with Pointer Capture.");
984 reason = "inbound event was dropped because there is no window with Pointer Capture";
985 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700986 case DropReason::NOT_DROPPED: {
987 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700988 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700989 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800990 }
991
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700992 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700993 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800994 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
995 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700996 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800997 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700998 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700999 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1000 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001001 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1002 synthesizeCancelationEventsForAllConnectionsLocked(options);
1003 } else {
1004 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1005 synthesizeCancelationEventsForAllConnectionsLocked(options);
1006 }
1007 break;
1008 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001009 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1010 break;
1011 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001012 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001013 case EventEntry::Type::CONFIGURATION_CHANGED:
1014 case EventEntry::Type::DEVICE_RESET: {
1015 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
1016 break;
1017 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001018 }
1019}
1020
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001021static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001022 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1023 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001024}
1025
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001026bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1027 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1028 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1029 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001030}
1031
1032bool InputDispatcher::isAppSwitchPendingLocked() {
1033 return mAppSwitchDueTime != LONG_LONG_MAX;
1034}
1035
1036void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1037 mAppSwitchDueTime = LONG_LONG_MAX;
1038
1039#if DEBUG_APP_SWITCH
1040 if (handled) {
1041 ALOGD("App switch has arrived.");
1042 } else {
1043 ALOGD("App switch was abandoned.");
1044 }
1045#endif
1046}
1047
Michael Wrightd02c5b62014-02-10 15:10:22 -08001048bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001049 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001050}
1051
1052bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001053 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001054 return false;
1055 }
1056
1057 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001058 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001059 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001060 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001061 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001062
1063 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001064 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001065 return true;
1066}
1067
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001068void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1069 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001070}
1071
1072void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001073 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001074 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001075 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001076 releaseInboundEventLocked(entry);
1077 }
1078 traceInboundQueueLengthLocked();
1079}
1080
1081void InputDispatcher::releasePendingEventLocked() {
1082 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001083 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001084 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001085 }
1086}
1087
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001088void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001089 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001090 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001091#if DEBUG_DISPATCH_CYCLE
1092 ALOGD("Injected inbound event was dropped.");
1093#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001094 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001095 }
1096 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001097 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001098 }
1099 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001100}
1101
1102void InputDispatcher::resetKeyRepeatLocked() {
1103 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001104 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001105 }
1106}
1107
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001108std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1109 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001110
Michael Wright2e732952014-09-24 13:26:59 -07001111 uint32_t policyFlags = entry->policyFlags &
1112 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001113
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001114 std::shared_ptr<KeyEntry> newEntry =
1115 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1116 entry->source, entry->displayId, policyFlags, entry->action,
1117 entry->flags, entry->keyCode, entry->scanCode,
1118 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001119
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001120 newEntry->syntheticRepeat = true;
1121 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001122 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001123 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001124}
1125
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001126bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001127 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001128#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001129 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130#endif
1131
1132 // Reset key repeating in case a keyboard device was added or removed or something.
1133 resetKeyRepeatLocked();
1134
1135 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001136 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1137 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001138 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001139 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001140 return true;
1141}
1142
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001143bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1144 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001145#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001146 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1147 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001148#endif
1149
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001150 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001151 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001152 synthesizeCancelationEventsForAllConnectionsLocked(options);
1153 return true;
1154}
1155
Vishnu Nairad321cd2020-08-20 16:40:21 -07001156void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001157 std::string_view reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001158 if (mPendingEvent != nullptr) {
1159 // Move the pending event to the front of the queue. This will give the chance
1160 // for the pending event to get dispatched to the newly focused window
1161 mInboundQueue.push_front(mPendingEvent);
1162 mPendingEvent = nullptr;
1163 }
1164
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001165 std::unique_ptr<FocusEntry> focusEntry =
1166 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1167 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001168
1169 // This event should go to the front of the queue, but behind all other focus events
1170 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001171 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001172 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001173 [](const std::shared_ptr<EventEntry>& event) {
1174 return event->type == EventEntry::Type::FOCUS;
1175 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001176
1177 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001178 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001179}
1180
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001181void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001182 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001183 if (channel == nullptr) {
1184 return; // Window has gone away
1185 }
1186 InputTarget target;
1187 target.inputChannel = channel;
1188 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1189 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001190 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1191 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001192 std::string reason = std::string("reason=").append(entry->reason);
1193 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001194 dispatchEventLocked(currentTime, entry, {target});
1195}
1196
Prabir Pradhan99987712020-11-10 18:43:05 -08001197void InputDispatcher::dispatchPointerCaptureChangedLocked(
1198 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1199 DropReason& dropReason) {
1200 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
1201 if (entry->pointerCaptureEnabled == haveWindowWithPointerCapture) {
1202 LOG_ALWAYS_FATAL_IF(mFocusedWindowRequestedPointerCapture,
1203 "The Pointer Capture state has already been dispatched to the window.");
1204 // Pointer capture was already forcefully disabled because of focus change.
1205 dropReason = DropReason::NOT_DROPPED;
1206 return;
1207 }
1208
1209 // Set drop reason for early returns
1210 dropReason = DropReason::NO_POINTER_CAPTURE;
1211
1212 sp<IBinder> token;
1213 if (entry->pointerCaptureEnabled) {
1214 // Enable Pointer Capture
1215 if (!mFocusedWindowRequestedPointerCapture) {
1216 // This can happen if a window requests capture and immediately releases capture.
1217 ALOGW("No window requested Pointer Capture.");
1218 return;
1219 }
1220 token = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
1221 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1222 mWindowTokenWithPointerCapture = token;
1223 } else {
1224 // Disable Pointer Capture
1225 token = mWindowTokenWithPointerCapture;
1226 mWindowTokenWithPointerCapture = nullptr;
1227 mFocusedWindowRequestedPointerCapture = false;
1228 }
1229
1230 auto channel = getInputChannelLocked(token);
1231 if (channel == nullptr) {
1232 // Window has gone away, clean up Pointer Capture state.
1233 mWindowTokenWithPointerCapture = nullptr;
1234 mFocusedWindowRequestedPointerCapture = false;
1235 return;
1236 }
1237 InputTarget target;
1238 target.inputChannel = channel;
1239 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1240 entry->dispatchInProgress = true;
1241 dispatchEventLocked(currentTime, entry, {target});
1242
1243 dropReason = DropReason::NOT_DROPPED;
1244}
1245
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001246bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001247 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001248 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001249 if (!entry->dispatchInProgress) {
1250 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1251 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1252 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1253 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001254 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001255 // We have seen two identical key downs in a row which indicates that the device
1256 // driver is automatically generating key repeats itself. We take note of the
1257 // repeat here, but we disable our own next key repeat timer since it is clear that
1258 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001259 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1260 // Make sure we don't get key down from a different device. If a different
1261 // device Id has same key pressed down, the new device Id will replace the
1262 // current one to hold the key repeat with repeat count reset.
1263 // In the future when got a KEY_UP on the device id, drop it and do not
1264 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001265 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1266 resetKeyRepeatLocked();
1267 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1268 } else {
1269 // Not a repeat. Save key down state in case we do see a repeat later.
1270 resetKeyRepeatLocked();
1271 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1272 }
1273 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001274 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1275 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001276 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001277#if DEBUG_INBOUND_EVENT_DETAILS
1278 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1279#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001280 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001281 resetKeyRepeatLocked();
1282 }
1283
1284 if (entry->repeatCount == 1) {
1285 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1286 } else {
1287 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1288 }
1289
1290 entry->dispatchInProgress = true;
1291
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001292 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001293 }
1294
1295 // Handle case where the policy asked us to try again later last time.
1296 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1297 if (currentTime < entry->interceptKeyWakeupTime) {
1298 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1299 *nextWakeupTime = entry->interceptKeyWakeupTime;
1300 }
1301 return false; // wait until next wakeup
1302 }
1303 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1304 entry->interceptKeyWakeupTime = 0;
1305 }
1306
1307 // Give the policy a chance to intercept the key.
1308 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1309 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001310 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001311 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001312 sp<IBinder> focusedWindowToken =
1313 getValueByKey(mFocusedWindowTokenByDisplay, getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001314 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001315 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001316 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001317 return false; // wait for the command to run
1318 } else {
1319 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1320 }
1321 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001322 if (*dropReason == DropReason::NOT_DROPPED) {
1323 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001324 }
1325 }
1326
1327 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001328 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001329 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001330 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1331 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001332 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001333 return true;
1334 }
1335
1336 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001337 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001338 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001339 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001340 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001341 return false;
1342 }
1343
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001344 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001345 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001346 return true;
1347 }
1348
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001349 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001350 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001351
1352 // Dispatch the key.
1353 dispatchEventLocked(currentTime, entry, inputTargets);
1354 return true;
1355}
1356
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001357void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001358#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001359 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001360 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1361 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001362 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1363 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1364 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001365#endif
1366}
1367
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001368bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001369 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001370 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001371 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001372 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001373 entry->dispatchInProgress = true;
1374
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001375 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001376 }
1377
1378 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001379 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001380 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001381 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1382 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001383 return true;
1384 }
1385
1386 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1387
1388 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001389 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001390
1391 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001392 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001393 if (isPointerEvent) {
1394 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001395 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001396 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001397 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001398 } else {
1399 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001400 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001401 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001402 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001403 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001404 return false;
1405 }
1406
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001407 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001408 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001409 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1410 return true;
1411 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001412 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001413 CancelationOptions::Mode mode(isPointerEvent
1414 ? CancelationOptions::CANCEL_POINTER_EVENTS
1415 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1416 CancelationOptions options(mode, "input event injection failed");
1417 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001418 return true;
1419 }
1420
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001421 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001422 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001423
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001424 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001425 std::unordered_map<int32_t, TouchState>::iterator it =
1426 mTouchStatesByDisplay.find(entry->displayId);
1427 if (it != mTouchStatesByDisplay.end()) {
1428 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001429 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001430 // The event has gone through these portal windows, so we add monitoring targets of
1431 // the corresponding displays as well.
1432 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001433 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001434 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001435 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001436 }
1437 }
1438 }
1439 }
1440
Michael Wrightd02c5b62014-02-10 15:10:22 -08001441 // Dispatch the motion.
1442 if (conflictingPointerActions) {
1443 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001444 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001445 synthesizeCancelationEventsForAllConnectionsLocked(options);
1446 }
1447 dispatchEventLocked(currentTime, entry, inputTargets);
1448 return true;
1449}
1450
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001451void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001452#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001453 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001454 ", policyFlags=0x%x, "
1455 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1456 "metaState=0x%x, buttonState=0x%x,"
1457 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001458 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1459 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1460 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001461
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001462 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001463 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001464 "x=%f, y=%f, pressure=%f, size=%f, "
1465 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1466 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001467 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1468 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1469 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1470 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1471 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1472 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1473 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1474 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1475 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1476 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001477 }
1478#endif
1479}
1480
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001481void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1482 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001483 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001484 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001485#if DEBUG_DISPATCH_CYCLE
1486 ALOGD("dispatchEventToCurrentInputTargets");
1487#endif
1488
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001489 updateInteractionTokensLocked(*eventEntry, inputTargets);
1490
Michael Wrightd02c5b62014-02-10 15:10:22 -08001491 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1492
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001493 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001494
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001495 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001496 sp<Connection> connection =
1497 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001498 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001499 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001500 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001501 if (DEBUG_FOCUS) {
1502 ALOGD("Dropping event delivery to target with channel '%s' because it "
1503 "is no longer registered with the input dispatcher.",
1504 inputTarget.inputChannel->getName().c_str());
1505 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001506 }
1507 }
1508}
1509
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001510void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1511 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1512 // If the policy decides to close the app, we will get a channel removal event via
1513 // unregisterInputChannel, and will clean up the connection that way. We are already not
1514 // sending new pointers to the connection when it blocked, but focused events will continue to
1515 // pile up.
1516 ALOGW("Canceling events for %s because it is unresponsive",
1517 connection->inputChannel->getName().c_str());
1518 if (connection->status == Connection::STATUS_NORMAL) {
1519 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1520 "application not responding");
1521 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001522 }
1523}
1524
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001525void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001526 if (DEBUG_FOCUS) {
1527 ALOGD("Resetting ANR timeouts.");
1528 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001529
1530 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001531 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001532 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001533}
1534
Tiger Huang721e26f2018-07-24 22:26:19 +08001535/**
1536 * Get the display id that the given event should go to. If this event specifies a valid display id,
1537 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1538 * Focused display is the display that the user most recently interacted with.
1539 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001540int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001541 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001542 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001543 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001544 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1545 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001546 break;
1547 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001548 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001549 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1550 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001551 break;
1552 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001553 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001554 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001555 case EventEntry::Type::CONFIGURATION_CHANGED:
1556 case EventEntry::Type::DEVICE_RESET: {
1557 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001558 return ADISPLAY_ID_NONE;
1559 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001560 }
1561 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1562}
1563
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001564bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1565 const char* focusedWindowName) {
1566 if (mAnrTracker.empty()) {
1567 // already processed all events that we waited for
1568 mKeyIsWaitingForEventsTimeout = std::nullopt;
1569 return false;
1570 }
1571
1572 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1573 // Start the timer
1574 ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
1575 "focus to change",
1576 focusedWindowName);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001577 mKeyIsWaitingForEventsTimeout = currentTime +
1578 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1579 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001580 return true;
1581 }
1582
1583 // We still have pending events, and already started the timer
1584 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1585 return true; // Still waiting
1586 }
1587
1588 // Waited too long, and some connection still hasn't processed all motions
1589 // Just send the key to the focused window
1590 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1591 focusedWindowName);
1592 mKeyIsWaitingForEventsTimeout = std::nullopt;
1593 return false;
1594}
1595
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001596InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1597 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1598 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001599 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001600
Tiger Huang721e26f2018-07-24 22:26:19 +08001601 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001602 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001603 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001604 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1605
Michael Wrightd02c5b62014-02-10 15:10:22 -08001606 // If there is no currently focused window and no focused application
1607 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001608 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1609 ALOGI("Dropping %s event because there is no focused window or focused application in "
1610 "display %" PRId32 ".",
1611 EventEntry::typeToString(entry.type), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001612 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001613 }
1614
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001615 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1616 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1617 // start interacting with another application via touch (app switch). This code can be removed
1618 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1619 // an app is expected to have a focused window.
1620 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1621 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1622 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001623 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1624 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1625 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001626 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001627 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001628 ALOGW("Waiting because no window has focus but %s may eventually add a "
1629 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001630 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001631 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001632 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001633 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1634 // Already raised ANR. Drop the event
1635 ALOGE("Dropping %s event because there is no focused window",
1636 EventEntry::typeToString(entry.type));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001637 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001638 } else {
1639 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001640 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001641 }
1642 }
1643
1644 // we have a valid, non-null focused window
1645 resetNoFocusedWindowTimeoutLocked();
1646
Michael Wrightd02c5b62014-02-10 15:10:22 -08001647 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001648 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001649 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001650 }
1651
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001652 if (focusedWindowHandle->getInfo()->paused) {
1653 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001654 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001655 }
1656
1657 // If the event is a key event, then we must wait for all previous events to
1658 // complete before delivering it because previous events may have the
1659 // side-effect of transferring focus to a different window and we want to
1660 // ensure that the following keys are sent to the new window.
1661 //
1662 // Suppose the user touches a button in a window then immediately presses "A".
1663 // If the button causes a pop-up window to appear then we want to ensure that
1664 // the "A" key is delivered to the new pop-up window. This is because users
1665 // often anticipate pending UI changes when typing on a keyboard.
1666 // To obtain this behavior, we must serialize key events with respect to all
1667 // prior input events.
1668 if (entry.type == EventEntry::Type::KEY) {
1669 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1670 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001671 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001672 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001673 }
1674
1675 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001676 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001677 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1678 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001679
1680 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001681 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001682}
1683
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001684/**
1685 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1686 * that are currently unresponsive.
1687 */
1688std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1689 const std::vector<TouchedMonitor>& monitors) const {
1690 std::vector<TouchedMonitor> responsiveMonitors;
1691 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1692 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1693 sp<Connection> connection = getConnectionLocked(
1694 monitor.monitor.inputChannel->getConnectionToken());
1695 if (connection == nullptr) {
1696 ALOGE("Could not find connection for monitor %s",
1697 monitor.monitor.inputChannel->getName().c_str());
1698 return false;
1699 }
1700 if (!connection->responsive) {
1701 ALOGW("Unresponsive monitor %s will not get the new gesture",
1702 connection->inputChannel->getName().c_str());
1703 return false;
1704 }
1705 return true;
1706 });
1707 return responsiveMonitors;
1708}
1709
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001710InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1711 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1712 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001713 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001714 enum InjectionPermission {
1715 INJECTION_PERMISSION_UNKNOWN,
1716 INJECTION_PERMISSION_GRANTED,
1717 INJECTION_PERMISSION_DENIED
1718 };
1719
Michael Wrightd02c5b62014-02-10 15:10:22 -08001720 // For security reasons, we defer updating the touch state until we are sure that
1721 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001722 int32_t displayId = entry.displayId;
1723 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001724 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1725
1726 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001727 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001728 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001729 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1730 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001731
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001732 // Copy current touch state into tempTouchState.
1733 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1734 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001735 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001736 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001737 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1738 mTouchStatesByDisplay.find(displayId);
1739 if (oldStateIt != mTouchStatesByDisplay.end()) {
1740 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001741 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001742 }
1743
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001744 bool isSplit = tempTouchState.split;
1745 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1746 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1747 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001748 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1749 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1750 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1751 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1752 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001753 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001754 bool wrongDevice = false;
1755 if (newGesture) {
1756 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001757 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001758 ALOGI("Dropping event because a pointer for a different device is already down "
1759 "in display %" PRId32,
1760 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001761 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001762 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001763 switchedDevice = false;
1764 wrongDevice = true;
1765 goto Failed;
1766 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001767 tempTouchState.reset();
1768 tempTouchState.down = down;
1769 tempTouchState.deviceId = entry.deviceId;
1770 tempTouchState.source = entry.source;
1771 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001772 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001773 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001774 ALOGI("Dropping move event because a pointer for a different device is already active "
1775 "in display %" PRId32,
1776 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001777 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001778 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001779 switchedDevice = false;
1780 wrongDevice = true;
1781 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001782 }
1783
1784 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1785 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1786
Garfield Tan00f511d2019-06-12 16:55:40 -07001787 int32_t x;
1788 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001789 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001790 // Always dispatch mouse events to cursor position.
1791 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001792 x = int32_t(entry.xCursorPosition);
1793 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001794 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001795 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1796 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001797 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001798 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001799 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001800 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1801 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001802
1803 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001804 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001805 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001806
Michael Wrightd02c5b62014-02-10 15:10:22 -08001807 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001808 if (newTouchedWindowHandle != nullptr &&
1809 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001810 // New window supports splitting, but we should never split mouse events.
1811 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001812 } else if (isSplit) {
1813 // New window does not support splitting but we have already split events.
1814 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001815 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001816 }
1817
1818 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001819 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001820 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001821 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001822 }
1823
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001824 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1825 ALOGI("Not sending touch event to %s because it is paused",
1826 newTouchedWindowHandle->getName().c_str());
1827 newTouchedWindowHandle = nullptr;
1828 }
1829
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001830 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001831 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001832 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1833 if (!isResponsive) {
1834 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001835 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1836 newTouchedWindowHandle = nullptr;
1837 }
1838 }
1839
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001840 // Drop events that can't be trusted due to occlusion
1841 if (newTouchedWindowHandle != nullptr &&
1842 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1843 TouchOcclusionInfo occlusionInfo =
1844 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001845 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001846 if (DEBUG_TOUCH_OCCLUSION) {
1847 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1848 for (const auto& log : occlusionInfo.debugInfo) {
1849 ALOGD("%s", log.c_str());
1850 }
1851 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001852 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
1853 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1854 ALOGW("Dropping untrusted touch event due to %s/%d",
1855 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1856 newTouchedWindowHandle = nullptr;
1857 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001858 }
1859 }
1860
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001861 // Also don't send the new touch event to unresponsive gesture monitors
1862 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1863
Michael Wright3dd60e22019-03-27 22:06:44 +00001864 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1865 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001866 "(%d, %d) in display %" PRId32 ".",
1867 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001868 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001869 goto Failed;
1870 }
1871
1872 if (newTouchedWindowHandle != nullptr) {
1873 // Set target flags.
1874 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1875 if (isSplit) {
1876 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001877 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001878 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1879 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1880 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1881 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1882 }
1883
1884 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07001885 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
1886 newHoverWindowHandle = nullptr;
1887 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001888 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00001889 }
1890
1891 // Update the temporary touch state.
1892 BitSet32 pointerIds;
1893 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001894 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001895 pointerIds.markBit(pointerId);
1896 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001897 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001898 }
1899
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001900 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001901 } else {
1902 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1903
1904 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001905 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001906 if (DEBUG_FOCUS) {
1907 ALOGD("Dropping event because the pointer is not down or we previously "
1908 "dropped the pointer down event in display %" PRId32,
1909 displayId);
1910 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001911 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001912 goto Failed;
1913 }
1914
1915 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001916 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001917 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001918 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1919 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920
1921 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001922 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07001923 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001924 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1925 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001926 if (DEBUG_FOCUS) {
1927 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1928 oldTouchedWindowHandle->getName().c_str(),
1929 newTouchedWindowHandle->getName().c_str(), displayId);
1930 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001931 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001932 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1933 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1934 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001935
1936 // Make a slippery entrance into the new window.
1937 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1938 isSplit = true;
1939 }
1940
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001941 int32_t targetFlags =
1942 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001943 if (isSplit) {
1944 targetFlags |= InputTarget::FLAG_SPLIT;
1945 }
1946 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1947 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1948 }
1949
1950 BitSet32 pointerIds;
1951 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001952 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001953 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001954 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001955 }
1956 }
1957 }
1958
1959 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07001960 // Let the previous window know that the hover sequence is over, unless we already did it
1961 // when dispatching it as is to newTouchedWindowHandle.
1962 if (mLastHoverWindowHandle != nullptr &&
1963 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
1964 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001965#if DEBUG_HOVER
1966 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001967 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001968#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001969 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1970 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001971 }
1972
Garfield Tandf26e862020-07-01 20:18:19 -07001973 // Let the new window know that the hover sequence is starting, unless we already did it
1974 // when dispatching it as is to newTouchedWindowHandle.
1975 if (newHoverWindowHandle != nullptr &&
1976 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
1977 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001978#if DEBUG_HOVER
1979 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001980 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001981#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001982 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1983 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1984 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001985 }
1986 }
1987
1988 // Check permission to inject into all touched foreground windows and ensure there
1989 // is at least one touched foreground window.
1990 {
1991 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001992 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001993 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1994 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001995 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001996 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001997 injectionPermission = INJECTION_PERMISSION_DENIED;
1998 goto Failed;
1999 }
2000 }
2001 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002002 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002003 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002004 ALOGI("Dropping event because there is no touched foreground window in display "
2005 "%" PRId32 " or gesture monitor to receive it.",
2006 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002007 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002008 goto Failed;
2009 }
2010
2011 // Permission granted to injection into all touched foreground windows.
2012 injectionPermission = INJECTION_PERMISSION_GRANTED;
2013 }
2014
2015 // Check whether windows listening for outside touches are owned by the same UID. If it is
2016 // set the policy flag that we will not reveal coordinate information to this window.
2017 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2018 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002019 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002020 if (foregroundWindowHandle) {
2021 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002022 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002023 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2024 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
2025 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002026 tempTouchState.addOrUpdateWindow(inputWindowHandle,
2027 InputTarget::FLAG_ZERO_COORDS,
2028 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002029 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002030 }
2031 }
2032 }
2033 }
2034
Michael Wrightd02c5b62014-02-10 15:10:22 -08002035 // If this is the first pointer going down and the touched window has a wallpaper
2036 // then also add the touched wallpaper windows so they are locked in for the duration
2037 // of the touch gesture.
2038 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2039 // engine only supports touch events. We would need to add a mechanism similar
2040 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2041 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2042 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002043 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002044 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07002045 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002046 getWindowHandlesLocked(displayId);
2047 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002048 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002049 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01002050 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002051 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002052 .addOrUpdateWindow(windowHandle,
2053 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2054 InputTarget::
2055 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2056 InputTarget::FLAG_DISPATCH_AS_IS,
2057 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002058 }
2059 }
2060 }
2061 }
2062
2063 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002064 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002065
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002066 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002068 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002069 }
2070
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002071 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002072 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002073 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002074 }
2075
Michael Wrightd02c5b62014-02-10 15:10:22 -08002076 // Drop the outside or hover touch windows since we will not care about them
2077 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002078 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002079
2080Failed:
2081 // Check injection permission once and for all.
2082 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002083 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002084 injectionPermission = INJECTION_PERMISSION_GRANTED;
2085 } else {
2086 injectionPermission = INJECTION_PERMISSION_DENIED;
2087 }
2088 }
2089
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002090 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2091 return injectionResult;
2092 }
2093
Michael Wrightd02c5b62014-02-10 15:10:22 -08002094 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002095 if (!wrongDevice) {
2096 if (switchedDevice) {
2097 if (DEBUG_FOCUS) {
2098 ALOGD("Conflicting pointer actions: Switched to a different device.");
2099 }
2100 *outConflictingPointerActions = true;
2101 }
2102
2103 if (isHoverAction) {
2104 // Started hovering, therefore no longer down.
2105 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002106 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002107 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2108 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002109 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002110 *outConflictingPointerActions = true;
2111 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002112 tempTouchState.reset();
2113 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2114 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2115 tempTouchState.deviceId = entry.deviceId;
2116 tempTouchState.source = entry.source;
2117 tempTouchState.displayId = displayId;
2118 }
2119 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2120 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2121 // All pointers up or canceled.
2122 tempTouchState.reset();
2123 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2124 // First pointer went down.
2125 if (oldState && oldState->down) {
2126 if (DEBUG_FOCUS) {
2127 ALOGD("Conflicting pointer actions: Down received while already down.");
2128 }
2129 *outConflictingPointerActions = true;
2130 }
2131 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2132 // One pointer went up.
2133 if (isSplit) {
2134 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2135 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002136
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002137 for (size_t i = 0; i < tempTouchState.windows.size();) {
2138 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2139 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2140 touchedWindow.pointerIds.clearBit(pointerId);
2141 if (touchedWindow.pointerIds.isEmpty()) {
2142 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2143 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002144 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002145 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002146 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002147 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002148 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002149 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002150
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002151 // Save changes unless the action was scroll in which case the temporary touch
2152 // state was only valid for this one action.
2153 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2154 if (tempTouchState.displayId >= 0) {
2155 mTouchStatesByDisplay[displayId] = tempTouchState;
2156 } else {
2157 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002158 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002159 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002160
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002161 // Update hover state.
2162 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002163 }
2164
Michael Wrightd02c5b62014-02-10 15:10:22 -08002165 return injectionResult;
2166}
2167
2168void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002169 int32_t targetFlags, BitSet32 pointerIds,
2170 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002171 std::vector<InputTarget>::iterator it =
2172 std::find_if(inputTargets.begin(), inputTargets.end(),
2173 [&windowHandle](const InputTarget& inputTarget) {
2174 return inputTarget.inputChannel->getConnectionToken() ==
2175 windowHandle->getToken();
2176 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002177
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002178 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002179
2180 if (it == inputTargets.end()) {
2181 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002182 std::shared_ptr<InputChannel> inputChannel =
2183 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002184 if (inputChannel == nullptr) {
2185 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2186 return;
2187 }
2188 inputTarget.inputChannel = inputChannel;
2189 inputTarget.flags = targetFlags;
2190 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2191 inputTargets.push_back(inputTarget);
2192 it = inputTargets.end() - 1;
2193 }
2194
2195 ALOG_ASSERT(it->flags == targetFlags);
2196 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2197
chaviw1ff3d1e2020-07-01 15:53:47 -07002198 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002199}
2200
Michael Wright3dd60e22019-03-27 22:06:44 +00002201void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002202 int32_t displayId, float xOffset,
2203 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002204 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2205 mGlobalMonitorsByDisplay.find(displayId);
2206
2207 if (it != mGlobalMonitorsByDisplay.end()) {
2208 const std::vector<Monitor>& monitors = it->second;
2209 for (const Monitor& monitor : monitors) {
2210 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002211 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002212 }
2213}
2214
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002215void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2216 float yOffset,
2217 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002218 InputTarget target;
2219 target.inputChannel = monitor.inputChannel;
2220 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002221 ui::Transform t;
2222 t.set(xOffset, yOffset);
2223 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002224 inputTargets.push_back(target);
2225}
2226
Michael Wrightd02c5b62014-02-10 15:10:22 -08002227bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002228 const InjectionState* injectionState) {
2229 if (injectionState &&
2230 (windowHandle == nullptr ||
2231 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2232 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002233 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002234 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002235 "owned by uid %d",
2236 injectionState->injectorPid, injectionState->injectorUid,
2237 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002238 } else {
2239 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002240 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002241 }
2242 return false;
2243 }
2244 return true;
2245}
2246
Robert Carrc9bf1d32020-04-13 17:21:08 -07002247/**
2248 * Indicate whether one window handle should be considered as obscuring
2249 * another window handle. We only check a few preconditions. Actually
2250 * checking the bounds is left to the caller.
2251 */
2252static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2253 const sp<InputWindowHandle>& otherHandle) {
2254 // Compare by token so cloned layers aren't counted
2255 if (haveSameToken(windowHandle, otherHandle)) {
2256 return false;
2257 }
2258 auto info = windowHandle->getInfo();
2259 auto otherInfo = otherHandle->getInfo();
2260 if (!otherInfo->visible) {
2261 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002262 } else if (otherInfo->alpha == 0 &&
2263 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2264 // Those act as if they were invisible, so we don't need to flag them.
2265 // We do want to potentially flag touchable windows even if they have 0
2266 // opacity, since they can consume touches and alter the effects of the
2267 // user interaction (eg. apps that rely on
2268 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2269 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2270 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002271 } else if (info->ownerUid == otherInfo->ownerUid) {
2272 // If ownerUid is the same we don't generate occlusion events as there
2273 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002274 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002275 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002276 return false;
2277 } else if (otherInfo->displayId != info->displayId) {
2278 return false;
2279 }
2280 return true;
2281}
2282
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002283/**
2284 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2285 * untrusted, one should check:
2286 *
2287 * 1. If result.hasBlockingOcclusion is true.
2288 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2289 * BLOCK_UNTRUSTED.
2290 *
2291 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2292 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2293 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2294 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2295 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2296 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2297 *
2298 * If neither of those is true, then it means the touch can be allowed.
2299 */
2300InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2301 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002302 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2303 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002304 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2305 TouchOcclusionInfo info;
2306 info.hasBlockingOcclusion = false;
2307 info.obscuringOpacity = 0;
2308 info.obscuringUid = -1;
2309 std::map<int32_t, float> opacityByUid;
2310 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2311 if (windowHandle == otherHandle) {
2312 break; // All future windows are below us. Exit early.
2313 }
2314 const InputWindowInfo* otherInfo = otherHandle->getInfo();
2315 if (canBeObscuredBy(windowHandle, otherHandle) &&
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002316 windowInfo->ownerUid != otherInfo->ownerUid && otherInfo->frameContainsPoint(x, y)) {
2317 if (DEBUG_TOUCH_OCCLUSION) {
2318 info.debugInfo.push_back(
2319 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2320 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002321 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2322 // we perform the checks below to see if the touch can be propagated or not based on the
2323 // window's touch occlusion mode
2324 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2325 info.hasBlockingOcclusion = true;
2326 info.obscuringUid = otherInfo->ownerUid;
2327 info.obscuringPackage = otherInfo->packageName;
2328 break;
2329 }
2330 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2331 uint32_t uid = otherInfo->ownerUid;
2332 float opacity =
2333 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2334 // Given windows A and B:
2335 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2336 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2337 opacityByUid[uid] = opacity;
2338 if (opacity > info.obscuringOpacity) {
2339 info.obscuringOpacity = opacity;
2340 info.obscuringUid = uid;
2341 info.obscuringPackage = otherInfo->packageName;
2342 }
2343 }
2344 }
2345 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002346 if (DEBUG_TOUCH_OCCLUSION) {
2347 info.debugInfo.push_back(
2348 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2349 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002350 return info;
2351}
2352
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002353std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2354 bool isTouchedWindow) const {
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002355 return StringPrintf(INDENT2 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32
2356 ", mode=%s, alpha=%.2f, "
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002357 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2358 "], touchableRegion=%s, window={%s}, applicationInfo=%s, "
2359 "flags={%s}, inputFeatures={%s}, hasToken=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002360 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002361 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002362 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002363 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2364 info->frameTop, info->frameRight, info->frameBottom,
2365 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002366 info->applicationInfo.name.c_str(), info->flags.string().c_str(),
2367 info->inputFeatures.string().c_str(), toString(info->token != nullptr));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002368}
2369
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002370bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2371 if (occlusionInfo.hasBlockingOcclusion) {
2372 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2373 occlusionInfo.obscuringUid);
2374 return false;
2375 }
2376 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2377 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2378 "%.2f, maximum allowed = %.2f)",
2379 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2380 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2381 return false;
2382 }
2383 return true;
2384}
2385
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002386bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2387 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002388 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002389 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002390 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002391 if (windowHandle == otherHandle) {
2392 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002393 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002394 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002395 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002396 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002397 return true;
2398 }
2399 }
2400 return false;
2401}
2402
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002403bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2404 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002405 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002406 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002407 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002408 if (windowHandle == otherHandle) {
2409 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002410 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002411 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002412 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002413 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002414 return true;
2415 }
2416 }
2417 return false;
2418}
2419
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002420std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002421 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002422 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002423 if (applicationHandle != nullptr) {
2424 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002425 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002426 } else {
2427 return applicationHandle->getName();
2428 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002429 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002430 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002431 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002432 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002433 }
2434}
2435
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002436void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002437 if (eventEntry.type == EventEntry::Type::FOCUS ||
2438 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED) {
2439 // Focus or pointer capture changed events are passed to apps, but do not represent user
2440 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002441 return;
2442 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002443 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002444 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002445 if (focusedWindowHandle != nullptr) {
2446 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002447 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002448#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002449 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002450#endif
2451 return;
2452 }
2453 }
2454
2455 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002456 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002457 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002458 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2459 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002460 return;
2461 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002462
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002463 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002464 eventType = USER_ACTIVITY_EVENT_TOUCH;
2465 }
2466 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002467 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002468 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002469 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2470 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002471 return;
2472 }
2473 eventType = USER_ACTIVITY_EVENT_BUTTON;
2474 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002475 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002476 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002477 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002478 case EventEntry::Type::DEVICE_RESET:
2479 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002480 LOG_ALWAYS_FATAL("%s events are not user activity",
2481 EventEntry::typeToString(eventEntry.type));
2482 break;
2483 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002484 }
2485
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002486 std::unique_ptr<CommandEntry> commandEntry =
2487 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002488 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002489 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002490 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002491}
2492
2493void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002494 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002495 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002496 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002497 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002498 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002499 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002500 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002501 ATRACE_NAME(message.c_str());
2502 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002503#if DEBUG_DISPATCH_CYCLE
2504 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002505 "globalScaleFactor=%f, pointerIds=0x%x %s",
2506 connection->getInputChannelName().c_str(), inputTarget.flags,
2507 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2508 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002509#endif
2510
2511 // Skip this event if the connection status is not normal.
2512 // We don't want to enqueue additional outbound events if the connection is broken.
2513 if (connection->status != Connection::STATUS_NORMAL) {
2514#if DEBUG_DISPATCH_CYCLE
2515 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002516 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002517#endif
2518 return;
2519 }
2520
2521 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002522 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2523 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2524 "Entry type %s should not have FLAG_SPLIT",
2525 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002526
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002527 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002528 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002529 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002530 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002531 if (!splitMotionEntry) {
2532 return; // split event was dropped
2533 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002534 if (DEBUG_FOCUS) {
2535 ALOGD("channel '%s' ~ Split motion event.",
2536 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002537 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002538 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002539 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2540 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002541 return;
2542 }
2543 }
2544
2545 // Not splitting. Enqueue dispatch entries for the event as is.
2546 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2547}
2548
2549void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002550 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002551 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002552 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002553 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002554 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002555 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002556 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002557 ATRACE_NAME(message.c_str());
2558 }
2559
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002560 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002561
2562 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002563 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002564 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002565 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002566 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002567 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002568 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002569 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002570 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002571 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002572 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002573 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002574 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002575
2576 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002577 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002578 startDispatchCycleLocked(currentTime, connection);
2579 }
2580}
2581
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002582void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002583 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002584 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002585 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002586 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002587 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2588 connection->getInputChannelName().c_str(),
2589 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002590 ATRACE_NAME(message.c_str());
2591 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002592 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002593 if (!(inputTargetFlags & dispatchMode)) {
2594 return;
2595 }
2596 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2597
2598 // This is a new event.
2599 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002600 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002601 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002602
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002603 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2604 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002605 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002606 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002607 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002608 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002609 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002610 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002611 dispatchEntry->resolvedAction = keyEntry.action;
2612 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002613
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002614 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2615 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002616#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002617 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2618 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002619#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002620 return; // skip the inconsistent event
2621 }
2622 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002623 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002624
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002625 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002626 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002627 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2628 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2629 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2630 static_cast<int32_t>(IdGenerator::Source::OTHER);
2631 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002632 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2633 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2634 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2635 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2636 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2637 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2638 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2639 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2640 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2641 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2642 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002643 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002644 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002645 }
2646 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002647 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2648 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002649#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002650 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2651 "event",
2652 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002653#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002654 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2655 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002656
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002657 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002658 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2659 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2660 }
2661 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2662 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2663 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002664
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002665 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2666 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002667#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002668 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2669 "event",
2670 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002671#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002672 return; // skip the inconsistent event
2673 }
2674
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002675 dispatchEntry->resolvedEventId =
2676 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2677 ? mIdGenerator.nextId()
2678 : motionEntry.id;
2679 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2680 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2681 ") to MotionEvent(id=0x%" PRIx32 ").",
2682 motionEntry.id, dispatchEntry->resolvedEventId);
2683 ATRACE_NAME(message.c_str());
2684 }
2685
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002686 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002687 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002688
2689 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002690 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002691 case EventEntry::Type::FOCUS:
2692 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002693 break;
2694 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002695 case EventEntry::Type::CONFIGURATION_CHANGED:
2696 case EventEntry::Type::DEVICE_RESET: {
2697 LOG_ALWAYS_FATAL("%s events should not go to apps",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002698 EventEntry::typeToString(newEntry.type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002699 break;
2700 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002701 }
2702
2703 // Remember that we are waiting for this dispatch to complete.
2704 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002705 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002706 }
2707
2708 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002709 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002710 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002711}
2712
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002713/**
2714 * This function is purely for debugging. It helps us understand where the user interaction
2715 * was taking place. For example, if user is touching launcher, we will see a log that user
2716 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2717 * We will see both launcher and wallpaper in that list.
2718 * Once the interaction with a particular set of connections starts, no new logs will be printed
2719 * until the set of interacted connections changes.
2720 *
2721 * The following items are skipped, to reduce the logspam:
2722 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2723 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2724 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2725 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2726 * Both of those ACTION_UP events would not be logged
2727 * Monitors (both gesture and global): any gesture monitors or global monitors receiving events
2728 * will not be logged. This is omitted to reduce the amount of data printed.
2729 * If you see <none>, it's likely that one of the gesture monitors pilfered the event, and therefore
2730 * gesture monitor is the only connection receiving the remainder of the gesture.
2731 */
2732void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2733 const std::vector<InputTarget>& targets) {
2734 // Skip ACTION_UP events, and all events other than keys and motions
2735 if (entry.type == EventEntry::Type::KEY) {
2736 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2737 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2738 return;
2739 }
2740 } else if (entry.type == EventEntry::Type::MOTION) {
2741 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2742 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2743 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2744 return;
2745 }
2746 } else {
2747 return; // Not a key or a motion
2748 }
2749
2750 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2751 std::vector<sp<Connection>> newConnections;
2752 for (const InputTarget& target : targets) {
2753 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2754 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2755 continue; // Skip windows that receive ACTION_OUTSIDE
2756 }
2757
2758 sp<IBinder> token = target.inputChannel->getConnectionToken();
2759 sp<Connection> connection = getConnectionLocked(token);
2760 if (connection == nullptr || connection->monitor) {
2761 continue; // We only need to keep track of the non-monitor connections.
2762 }
2763 newConnectionTokens.insert(std::move(token));
2764 newConnections.emplace_back(connection);
2765 }
2766 if (newConnectionTokens == mInteractionConnectionTokens) {
2767 return; // no change
2768 }
2769 mInteractionConnectionTokens = newConnectionTokens;
2770
2771 std::string windowList;
2772 for (const sp<Connection>& connection : newConnections) {
2773 windowList += connection->getWindowName() + ", ";
2774 }
2775 std::string message = "Interaction with windows: " + windowList;
2776 if (windowList.empty()) {
2777 message += "<none>";
2778 }
2779 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2780}
2781
chaviwfd6d3512019-03-25 13:23:49 -07002782void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002783 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002784 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002785 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2786 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002787 return;
2788 }
2789
Vishnu Nairad321cd2020-08-20 16:40:21 -07002790 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
2791 if (focusedToken == token) {
2792 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002793 return;
2794 }
2795
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002796 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2797 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002798 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002799 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002800}
2801
2802void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002803 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002804 if (ATRACE_ENABLED()) {
2805 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002806 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002807 ATRACE_NAME(message.c_str());
2808 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002809#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002810 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002811#endif
2812
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002813 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2814 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002815 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002816 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002817 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002818 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002819
2820 // Publish the event.
2821 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002822 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
2823 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002824 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002825 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2826 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002827
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002828 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002829 status = connection->inputPublisher
2830 .publishKeyEvent(dispatchEntry->seq,
2831 dispatchEntry->resolvedEventId, keyEntry.deviceId,
2832 keyEntry.source, keyEntry.displayId,
2833 std::move(hmac), dispatchEntry->resolvedAction,
2834 dispatchEntry->resolvedFlags, keyEntry.keyCode,
2835 keyEntry.scanCode, keyEntry.metaState,
2836 keyEntry.repeatCount, keyEntry.downTime,
2837 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002838 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002839 }
2840
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002841 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002842 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002843
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002844 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002845 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002846
chaviw82357092020-01-28 13:13:06 -08002847 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002848 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002849 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2850 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002851 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002852 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
2853 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002854 // Don't apply window scale here since we don't want scale to affect raw
2855 // coordinates. The scale will be sent back to the client and applied
2856 // later when requesting relative coordinates.
2857 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2858 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002859 }
2860 usingCoords = scaledCoords;
2861 }
2862 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002863 // We don't want the dispatch target to know.
2864 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002865 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002866 scaledCoords[i].clear();
2867 }
2868 usingCoords = scaledCoords;
2869 }
2870 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002871
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002872 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002873
2874 // Publish the motion event.
2875 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002876 .publishMotionEvent(dispatchEntry->seq,
2877 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002878 motionEntry.deviceId, motionEntry.source,
2879 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002880 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002881 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002882 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002883 motionEntry.edgeFlags, motionEntry.metaState,
2884 motionEntry.buttonState,
2885 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07002886 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002887 motionEntry.xPrecision, motionEntry.yPrecision,
2888 motionEntry.xCursorPosition,
2889 motionEntry.yCursorPosition,
2890 motionEntry.downTime, motionEntry.eventTime,
2891 motionEntry.pointerCount,
2892 motionEntry.pointerProperties, usingCoords);
2893 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002894 break;
2895 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002896
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002897 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002898 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002899 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002900 focusEntry.id,
2901 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002902 mInTouchMode);
2903 break;
2904 }
2905
Prabir Pradhan99987712020-11-10 18:43:05 -08002906 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
2907 const auto& captureEntry =
2908 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
2909 status = connection->inputPublisher
2910 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
2911 captureEntry.pointerCaptureEnabled);
2912 break;
2913 }
2914
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002915 case EventEntry::Type::CONFIGURATION_CHANGED:
2916 case EventEntry::Type::DEVICE_RESET: {
2917 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002918 EventEntry::typeToString(eventEntry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002919 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002920 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002921 }
2922
2923 // Check the result.
2924 if (status) {
2925 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002926 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002927 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002928 "This is unexpected because the wait queue is empty, so the pipe "
2929 "should be empty and we shouldn't have any problems writing an "
2930 "event to it, status=%d",
2931 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002932 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2933 } else {
2934 // Pipe is full and we are waiting for the app to finish process some events
2935 // before sending more events to it.
2936#if DEBUG_DISPATCH_CYCLE
2937 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002938 "waiting for the application to catch up",
2939 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002940#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08002941 }
2942 } else {
2943 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002944 "status=%d",
2945 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002946 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2947 }
2948 return;
2949 }
2950
2951 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002952 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2953 connection->outboundQueue.end(),
2954 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002955 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002956 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002957 if (connection->responsive) {
2958 mAnrTracker.insert(dispatchEntry->timeoutTime,
2959 connection->inputChannel->getConnectionToken());
2960 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002961 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002962 }
2963}
2964
chaviw09c8d2d2020-08-24 15:48:26 -07002965std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
2966 size_t size;
2967 switch (event.type) {
2968 case VerifiedInputEvent::Type::KEY: {
2969 size = sizeof(VerifiedKeyEvent);
2970 break;
2971 }
2972 case VerifiedInputEvent::Type::MOTION: {
2973 size = sizeof(VerifiedMotionEvent);
2974 break;
2975 }
2976 }
2977 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
2978 return mHmacKeyManager.sign(start, size);
2979}
2980
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002981const std::array<uint8_t, 32> InputDispatcher::getSignature(
2982 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
2983 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
2984 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
2985 // Only sign events up and down events as the purely move events
2986 // are tied to their up/down counterparts so signing would be redundant.
2987 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
2988 verifiedEvent.actionMasked = actionMasked;
2989 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07002990 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002991 }
2992 return INVALID_HMAC;
2993}
2994
2995const std::array<uint8_t, 32> InputDispatcher::getSignature(
2996 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
2997 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
2998 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
2999 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003000 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003001}
3002
Michael Wrightd02c5b62014-02-10 15:10:22 -08003003void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003004 const sp<Connection>& connection, uint32_t seq,
3005 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003006#if DEBUG_DISPATCH_CYCLE
3007 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003008 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003009#endif
3010
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003011 if (connection->status == Connection::STATUS_BROKEN ||
3012 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003013 return;
3014 }
3015
3016 // Notify other system components and prepare to start the next dispatch cycle.
3017 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
3018}
3019
3020void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003021 const sp<Connection>& connection,
3022 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003023#if DEBUG_DISPATCH_CYCLE
3024 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003025 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003026#endif
3027
3028 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003029 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003030 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003031 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003032 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003033
3034 // The connection appears to be unrecoverably broken.
3035 // Ignore already broken or zombie connections.
3036 if (connection->status == Connection::STATUS_NORMAL) {
3037 connection->status = Connection::STATUS_BROKEN;
3038
3039 if (notify) {
3040 // Notify other system components.
3041 onDispatchCycleBrokenLocked(currentTime, connection);
3042 }
3043 }
3044}
3045
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003046void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3047 while (!queue.empty()) {
3048 DispatchEntry* dispatchEntry = queue.front();
3049 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003050 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003051 }
3052}
3053
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003054void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003055 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003056 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003057 }
3058 delete dispatchEntry;
3059}
3060
3061int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
3062 InputDispatcher* d = static_cast<InputDispatcher*>(data);
3063
3064 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003065 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003066
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003067 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003068 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003069 "fd=%d, events=0x%x",
3070 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003071 return 0; // remove the callback
3072 }
3073
3074 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003075 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003076 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3077 if (!(events & ALOOPER_EVENT_INPUT)) {
3078 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003079 "events=0x%x",
3080 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003081 return 1;
3082 }
3083
3084 nsecs_t currentTime = now();
3085 bool gotOne = false;
3086 status_t status;
3087 for (;;) {
3088 uint32_t seq;
3089 bool handled;
3090 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
3091 if (status) {
3092 break;
3093 }
3094 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
3095 gotOne = true;
3096 }
3097 if (gotOne) {
3098 d->runCommandsLockedInterruptible();
3099 if (status == WOULD_BLOCK) {
3100 return 1;
3101 }
3102 }
3103
3104 notify = status != DEAD_OBJECT || !connection->monitor;
3105 if (notify) {
3106 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003107 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003108 }
3109 } else {
3110 // Monitor channels are never explicitly unregistered.
3111 // We do it automatically when the remote endpoint is closed so don't warn
3112 // about them.
arthurhungd352cb32020-04-28 17:09:28 +08003113 const bool stillHaveWindowHandle =
3114 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3115 nullptr;
3116 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003117 if (notify) {
3118 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003119 "events=0x%x",
3120 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003121 }
3122 }
3123
Garfield Tan15601662020-09-22 15:32:38 -07003124 // Remove the channel.
3125 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003126 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003127 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003128}
3129
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003130void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003131 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003132 for (const auto& pair : mConnectionsByFd) {
3133 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003134 }
3135}
3136
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003137void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003138 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003139 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3140 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3141}
3142
3143void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3144 const CancelationOptions& options,
3145 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3146 for (const auto& it : monitorsByDisplay) {
3147 const std::vector<Monitor>& monitors = it.second;
3148 for (const Monitor& monitor : monitors) {
3149 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003150 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003151 }
3152}
3153
Michael Wrightd02c5b62014-02-10 15:10:22 -08003154void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003155 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003156 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003157 if (connection == nullptr) {
3158 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003159 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003160
3161 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003162}
3163
3164void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3165 const sp<Connection>& connection, const CancelationOptions& options) {
3166 if (connection->status == Connection::STATUS_BROKEN) {
3167 return;
3168 }
3169
3170 nsecs_t currentTime = now();
3171
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003172 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003173 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003174
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003175 if (cancelationEvents.empty()) {
3176 return;
3177 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003178#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003179 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3180 "with reality: %s, mode=%d.",
3181 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3182 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003183#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003184
3185 InputTarget target;
3186 sp<InputWindowHandle> windowHandle =
3187 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3188 if (windowHandle != nullptr) {
3189 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003190 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003191 target.globalScaleFactor = windowInfo->globalScaleFactor;
3192 }
3193 target.inputChannel = connection->inputChannel;
3194 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3195
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003196 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003197 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003198 switch (cancelationEventEntry->type) {
3199 case EventEntry::Type::KEY: {
3200 logOutboundKeyDetails("cancel - ",
3201 static_cast<const KeyEntry&>(*cancelationEventEntry));
3202 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003203 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003204 case EventEntry::Type::MOTION: {
3205 logOutboundMotionDetails("cancel - ",
3206 static_cast<const MotionEntry&>(*cancelationEventEntry));
3207 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003208 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003209 case EventEntry::Type::FOCUS:
3210 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3211 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
3212 EventEntry::typeToString(cancelationEventEntry->type));
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003213 break;
3214 }
3215 case EventEntry::Type::CONFIGURATION_CHANGED:
3216 case EventEntry::Type::DEVICE_RESET: {
3217 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3218 EventEntry::typeToString(cancelationEventEntry->type));
3219 break;
3220 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003221 }
3222
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003223 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3224 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003225 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003226
3227 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003228}
3229
Svet Ganov5d3bc372020-01-26 23:11:07 -08003230void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3231 const sp<Connection>& connection) {
3232 if (connection->status == Connection::STATUS_BROKEN) {
3233 return;
3234 }
3235
3236 nsecs_t currentTime = now();
3237
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003238 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003239 connection->inputState.synthesizePointerDownEvents(currentTime);
3240
3241 if (downEvents.empty()) {
3242 return;
3243 }
3244
3245#if DEBUG_OUTBOUND_EVENT_DETAILS
3246 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3247 connection->getInputChannelName().c_str(), downEvents.size());
3248#endif
3249
3250 InputTarget target;
3251 sp<InputWindowHandle> windowHandle =
3252 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3253 if (windowHandle != nullptr) {
3254 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003255 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003256 target.globalScaleFactor = windowInfo->globalScaleFactor;
3257 }
3258 target.inputChannel = connection->inputChannel;
3259 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3260
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003261 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003262 switch (downEventEntry->type) {
3263 case EventEntry::Type::MOTION: {
3264 logOutboundMotionDetails("down - ",
3265 static_cast<const MotionEntry&>(*downEventEntry));
3266 break;
3267 }
3268
3269 case EventEntry::Type::KEY:
3270 case EventEntry::Type::FOCUS:
3271 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003272 case EventEntry::Type::DEVICE_RESET:
3273 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003274 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3275 EventEntry::typeToString(downEventEntry->type));
3276 break;
3277 }
3278 }
3279
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003280 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3281 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003282 }
3283
3284 startDispatchCycleLocked(currentTime, connection);
3285}
3286
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003287std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3288 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003289 ALOG_ASSERT(pointerIds.value != 0);
3290
3291 uint32_t splitPointerIndexMap[MAX_POINTERS];
3292 PointerProperties splitPointerProperties[MAX_POINTERS];
3293 PointerCoords splitPointerCoords[MAX_POINTERS];
3294
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003295 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003296 uint32_t splitPointerCount = 0;
3297
3298 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003299 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003300 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003301 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003302 uint32_t pointerId = uint32_t(pointerProperties.id);
3303 if (pointerIds.hasBit(pointerId)) {
3304 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3305 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3306 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003307 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003308 splitPointerCount += 1;
3309 }
3310 }
3311
3312 if (splitPointerCount != pointerIds.count()) {
3313 // This is bad. We are missing some of the pointers that we expected to deliver.
3314 // Most likely this indicates that we received an ACTION_MOVE events that has
3315 // different pointer ids than we expected based on the previous ACTION_DOWN
3316 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3317 // in this way.
3318 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003319 "we expected there to be %d pointers. This probably means we received "
3320 "a broken sequence of pointer ids from the input device.",
3321 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003322 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003323 }
3324
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003325 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003326 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003327 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3328 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003329 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3330 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003331 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003332 uint32_t pointerId = uint32_t(pointerProperties.id);
3333 if (pointerIds.hasBit(pointerId)) {
3334 if (pointerIds.count() == 1) {
3335 // The first/last pointer went down/up.
3336 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003337 ? AMOTION_EVENT_ACTION_DOWN
3338 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003339 } else {
3340 // A secondary pointer went down/up.
3341 uint32_t splitPointerIndex = 0;
3342 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3343 splitPointerIndex += 1;
3344 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003345 action = maskedAction |
3346 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003347 }
3348 } else {
3349 // An unrelated pointer changed.
3350 action = AMOTION_EVENT_ACTION_MOVE;
3351 }
3352 }
3353
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003354 int32_t newId = mIdGenerator.nextId();
3355 if (ATRACE_ENABLED()) {
3356 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3357 ") to MotionEvent(id=0x%" PRIx32 ").",
3358 originalMotionEntry.id, newId);
3359 ATRACE_NAME(message.c_str());
3360 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003361 std::unique_ptr<MotionEntry> splitMotionEntry =
3362 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3363 originalMotionEntry.deviceId, originalMotionEntry.source,
3364 originalMotionEntry.displayId,
3365 originalMotionEntry.policyFlags, action,
3366 originalMotionEntry.actionButton,
3367 originalMotionEntry.flags, originalMotionEntry.metaState,
3368 originalMotionEntry.buttonState,
3369 originalMotionEntry.classification,
3370 originalMotionEntry.edgeFlags,
3371 originalMotionEntry.xPrecision,
3372 originalMotionEntry.yPrecision,
3373 originalMotionEntry.xCursorPosition,
3374 originalMotionEntry.yCursorPosition,
3375 originalMotionEntry.downTime, splitPointerCount,
3376 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003377
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003378 if (originalMotionEntry.injectionState) {
3379 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003380 splitMotionEntry->injectionState->refCount += 1;
3381 }
3382
3383 return splitMotionEntry;
3384}
3385
3386void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3387#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003388 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003389#endif
3390
3391 bool needWake;
3392 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003393 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003394
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003395 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3396 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3397 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003398 } // release lock
3399
3400 if (needWake) {
3401 mLooper->wake();
3402 }
3403}
3404
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003405/**
3406 * If one of the meta shortcuts is detected, process them here:
3407 * Meta + Backspace -> generate BACK
3408 * Meta + Enter -> generate HOME
3409 * This will potentially overwrite keyCode and metaState.
3410 */
3411void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003412 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003413 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3414 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3415 if (keyCode == AKEYCODE_DEL) {
3416 newKeyCode = AKEYCODE_BACK;
3417 } else if (keyCode == AKEYCODE_ENTER) {
3418 newKeyCode = AKEYCODE_HOME;
3419 }
3420 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003421 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003422 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003423 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003424 keyCode = newKeyCode;
3425 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3426 }
3427 } else if (action == AKEY_EVENT_ACTION_UP) {
3428 // In order to maintain a consistent stream of up and down events, check to see if the key
3429 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3430 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003431 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003432 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003433 auto replacementIt = mReplacedKeys.find(replacement);
3434 if (replacementIt != mReplacedKeys.end()) {
3435 keyCode = replacementIt->second;
3436 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003437 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3438 }
3439 }
3440}
3441
Michael Wrightd02c5b62014-02-10 15:10:22 -08003442void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3443#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003444 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3445 "policyFlags=0x%x, action=0x%x, "
3446 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3447 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3448 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3449 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003450#endif
3451 if (!validateKeyEvent(args->action)) {
3452 return;
3453 }
3454
3455 uint32_t policyFlags = args->policyFlags;
3456 int32_t flags = args->flags;
3457 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003458 // InputDispatcher tracks and generates key repeats on behalf of
3459 // whatever notifies it, so repeatCount should always be set to 0
3460 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003461 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3462 policyFlags |= POLICY_FLAG_VIRTUAL;
3463 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3464 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003465 if (policyFlags & POLICY_FLAG_FUNCTION) {
3466 metaState |= AMETA_FUNCTION_ON;
3467 }
3468
3469 policyFlags |= POLICY_FLAG_TRUSTED;
3470
Michael Wright78f24442014-08-06 15:55:28 -07003471 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003472 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003473
Michael Wrightd02c5b62014-02-10 15:10:22 -08003474 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003475 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003476 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3477 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003478
Michael Wright2b3c3302018-03-02 17:19:13 +00003479 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003480 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003481 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3482 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003483 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003484 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003485
Michael Wrightd02c5b62014-02-10 15:10:22 -08003486 bool needWake;
3487 { // acquire lock
3488 mLock.lock();
3489
3490 if (shouldSendKeyToInputFilterLocked(args)) {
3491 mLock.unlock();
3492
3493 policyFlags |= POLICY_FLAG_FILTERED;
3494 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3495 return; // event was consumed by the filter
3496 }
3497
3498 mLock.lock();
3499 }
3500
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003501 std::unique_ptr<KeyEntry> newEntry =
3502 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3503 args->displayId, policyFlags, args->action, flags,
3504 keyCode, args->scanCode, metaState, repeatCount,
3505 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003506
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003507 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003508 mLock.unlock();
3509 } // release lock
3510
3511 if (needWake) {
3512 mLooper->wake();
3513 }
3514}
3515
3516bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3517 return mInputFilterEnabled;
3518}
3519
3520void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3521#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003522 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3523 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003524 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3525 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003526 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003527 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3528 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3529 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3530 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003531 for (uint32_t i = 0; i < args->pointerCount; i++) {
3532 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003533 "x=%f, y=%f, pressure=%f, size=%f, "
3534 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3535 "orientation=%f",
3536 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3537 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3538 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3539 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3540 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3541 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3542 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3543 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3544 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3545 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003546 }
3547#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003548 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3549 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003550 return;
3551 }
3552
3553 uint32_t policyFlags = args->policyFlags;
3554 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003555
3556 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003557 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003558 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3559 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003560 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003561 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003562
3563 bool needWake;
3564 { // acquire lock
3565 mLock.lock();
3566
3567 if (shouldSendMotionToInputFilterLocked(args)) {
3568 mLock.unlock();
3569
3570 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003571 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003572 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3573 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003574 args->metaState, args->buttonState, args->classification, transform,
3575 args->xPrecision, args->yPrecision, args->xCursorPosition,
3576 args->yCursorPosition, args->downTime, args->eventTime,
3577 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003578
3579 policyFlags |= POLICY_FLAG_FILTERED;
3580 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3581 return; // event was consumed by the filter
3582 }
3583
3584 mLock.lock();
3585 }
3586
3587 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003588 std::unique_ptr<MotionEntry> newEntry =
3589 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3590 args->source, args->displayId, policyFlags,
3591 args->action, args->actionButton, args->flags,
3592 args->metaState, args->buttonState,
3593 args->classification, args->edgeFlags,
3594 args->xPrecision, args->yPrecision,
3595 args->xCursorPosition, args->yCursorPosition,
3596 args->downTime, args->pointerCount,
3597 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003598
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003599 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003600 mLock.unlock();
3601 } // release lock
3602
3603 if (needWake) {
3604 mLooper->wake();
3605 }
3606}
3607
3608bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003609 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003610}
3611
3612void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3613#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003614 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003615 "switchMask=0x%08x",
3616 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003617#endif
3618
3619 uint32_t policyFlags = args->policyFlags;
3620 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003621 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003622}
3623
3624void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3625#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003626 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3627 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003628#endif
3629
3630 bool needWake;
3631 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003632 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003633
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003634 std::unique_ptr<DeviceResetEntry> newEntry =
3635 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3636 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003637 } // release lock
3638
3639 if (needWake) {
3640 mLooper->wake();
3641 }
3642}
3643
Prabir Pradhan7e186182020-11-10 13:56:45 -08003644void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3645#if DEBUG_INBOUND_EVENT_DETAILS
3646 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3647 args->enabled ? "true" : "false");
3648#endif
3649
Prabir Pradhan99987712020-11-10 18:43:05 -08003650 bool needWake;
3651 { // acquire lock
3652 std::scoped_lock _l(mLock);
3653 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
3654 args->enabled);
3655 needWake = enqueueInboundEventLocked(std::move(entry));
3656 } // release lock
3657
3658 if (needWake) {
3659 mLooper->wake();
3660 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003661}
3662
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003663InputEventInjectionResult InputDispatcher::injectInputEvent(
3664 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3665 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003666#if DEBUG_INBOUND_EVENT_DETAILS
3667 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003668 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3669 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003670#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003671 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003672
3673 policyFlags |= POLICY_FLAG_INJECTED;
3674 if (hasInjectionPermission(injectorPid, injectorUid)) {
3675 policyFlags |= POLICY_FLAG_TRUSTED;
3676 }
3677
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003678 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003679 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003680 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003681 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3682 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003683 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003684 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003685 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003686
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003687 int32_t flags = incomingKey.getFlags();
3688 int32_t keyCode = incomingKey.getKeyCode();
3689 int32_t metaState = incomingKey.getMetaState();
3690 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003691 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003692 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003693 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003694 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3695 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3696 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003697
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003698 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3699 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003700 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003701
3702 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3703 android::base::Timer t;
3704 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3705 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3706 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3707 std::to_string(t.duration().count()).c_str());
3708 }
3709 }
3710
3711 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003712 std::unique_ptr<KeyEntry> injectedEntry =
3713 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3714 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3715 incomingKey.getDisplayId(), policyFlags, action,
3716 flags, keyCode, incomingKey.getScanCode(), metaState,
3717 incomingKey.getRepeatCount(),
3718 incomingKey.getDownTime());
3719 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003720 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003721 }
3722
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003723 case AINPUT_EVENT_TYPE_MOTION: {
3724 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3725 int32_t action = motionEvent->getAction();
3726 size_t pointerCount = motionEvent->getPointerCount();
3727 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3728 int32_t actionButton = motionEvent->getActionButton();
3729 int32_t displayId = motionEvent->getDisplayId();
3730 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003731 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003732 }
3733
3734 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3735 nsecs_t eventTime = motionEvent->getEventTime();
3736 android::base::Timer t;
3737 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3738 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3739 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3740 std::to_string(t.duration().count()).c_str());
3741 }
3742 }
3743
3744 mLock.lock();
3745 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3746 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003747 std::unique_ptr<MotionEntry> injectedEntry =
3748 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3749 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3750 motionEvent->getDisplayId(), policyFlags, action,
3751 actionButton, motionEvent->getFlags(),
3752 motionEvent->getMetaState(),
3753 motionEvent->getButtonState(),
3754 motionEvent->getClassification(),
3755 motionEvent->getEdgeFlags(),
3756 motionEvent->getXPrecision(),
3757 motionEvent->getYPrecision(),
3758 motionEvent->getRawXCursorPosition(),
3759 motionEvent->getRawYCursorPosition(),
3760 motionEvent->getDownTime(),
3761 uint32_t(pointerCount), pointerProperties,
3762 samplePointerCoords, motionEvent->getXOffset(),
3763 motionEvent->getYOffset());
3764 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003765 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3766 sampleEventTimes += 1;
3767 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003768 std::unique_ptr<MotionEntry> nextInjectedEntry =
3769 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3770 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3771 motionEvent->getDisplayId(), policyFlags,
3772 action, actionButton, motionEvent->getFlags(),
3773 motionEvent->getMetaState(),
3774 motionEvent->getButtonState(),
3775 motionEvent->getClassification(),
3776 motionEvent->getEdgeFlags(),
3777 motionEvent->getXPrecision(),
3778 motionEvent->getYPrecision(),
3779 motionEvent->getRawXCursorPosition(),
3780 motionEvent->getRawYCursorPosition(),
3781 motionEvent->getDownTime(),
3782 uint32_t(pointerCount), pointerProperties,
3783 samplePointerCoords,
3784 motionEvent->getXOffset(),
3785 motionEvent->getYOffset());
3786 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003787 }
3788 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003789 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003790
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003791 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003792 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003793 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003794 }
3795
3796 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003797 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003798 injectionState->injectionIsAsync = true;
3799 }
3800
3801 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003802 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003803
3804 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003805 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003806 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003807 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003808 }
3809
3810 mLock.unlock();
3811
3812 if (needWake) {
3813 mLooper->wake();
3814 }
3815
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003816 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003817 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003818 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003819
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003820 if (syncMode == InputEventInjectionSync::NONE) {
3821 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003822 } else {
3823 for (;;) {
3824 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003825 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003826 break;
3827 }
3828
3829 nsecs_t remainingTimeout = endTime - now();
3830 if (remainingTimeout <= 0) {
3831#if DEBUG_INJECTION
3832 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003833 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003834#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003835 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003836 break;
3837 }
3838
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003839 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003840 }
3841
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003842 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3843 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003844 while (injectionState->pendingForegroundDispatches != 0) {
3845#if DEBUG_INJECTION
3846 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003847 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848#endif
3849 nsecs_t remainingTimeout = endTime - now();
3850 if (remainingTimeout <= 0) {
3851#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003852 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3853 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003854#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003855 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003856 break;
3857 }
3858
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003859 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003860 }
3861 }
3862 }
3863
3864 injectionState->release();
3865 } // release lock
3866
3867#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003868 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003869 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003870#endif
3871
3872 return injectionResult;
3873}
3874
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003875std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05003876 std::array<uint8_t, 32> calculatedHmac;
3877 std::unique_ptr<VerifiedInputEvent> result;
3878 switch (event.getType()) {
3879 case AINPUT_EVENT_TYPE_KEY: {
3880 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
3881 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
3882 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003883 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05003884 break;
3885 }
3886 case AINPUT_EVENT_TYPE_MOTION: {
3887 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
3888 VerifiedMotionEvent verifiedMotionEvent =
3889 verifiedMotionEventFromMotionEvent(motionEvent);
3890 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003891 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05003892 break;
3893 }
3894 default: {
3895 ALOGE("Cannot verify events of type %" PRId32, event.getType());
3896 return nullptr;
3897 }
3898 }
3899 if (calculatedHmac == INVALID_HMAC) {
3900 return nullptr;
3901 }
3902 if (calculatedHmac != event.getHmac()) {
3903 return nullptr;
3904 }
3905 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003906}
3907
Michael Wrightd02c5b62014-02-10 15:10:22 -08003908bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003909 return injectorUid == 0 ||
3910 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003911}
3912
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003913void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003914 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003915 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003916 if (injectionState) {
3917#if DEBUG_INJECTION
3918 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003919 "injectorPid=%d, injectorUid=%d",
3920 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003921#endif
3922
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003923 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003924 // Log the outcome since the injector did not wait for the injection result.
3925 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003926 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003927 ALOGV("Asynchronous input event injection succeeded.");
3928 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003929 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003930 ALOGW("Asynchronous input event injection failed.");
3931 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003932 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003933 ALOGW("Asynchronous input event injection permission denied.");
3934 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003935 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003936 ALOGW("Asynchronous input event injection timed out.");
3937 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003938 case InputEventInjectionResult::PENDING:
3939 ALOGE("Setting result to 'PENDING' for asynchronous injection");
3940 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003941 }
3942 }
3943
3944 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003945 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003946 }
3947}
3948
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003949void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
3950 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003951 if (injectionState) {
3952 injectionState->pendingForegroundDispatches += 1;
3953 }
3954}
3955
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003956void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
3957 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003958 if (injectionState) {
3959 injectionState->pendingForegroundDispatches -= 1;
3960
3961 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003962 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003963 }
3964 }
3965}
3966
Vishnu Nairad321cd2020-08-20 16:40:21 -07003967const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003968 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003969 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
3970 auto it = mWindowHandlesByDisplay.find(displayId);
3971 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08003972}
3973
Michael Wrightd02c5b62014-02-10 15:10:22 -08003974sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003975 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08003976 if (windowHandleToken == nullptr) {
3977 return nullptr;
3978 }
3979
Arthur Hungb92218b2018-08-14 12:00:21 +08003980 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003981 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003982 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003983 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003984 return windowHandle;
3985 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003986 }
3987 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003988 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003989}
3990
Vishnu Nairad321cd2020-08-20 16:40:21 -07003991sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
3992 int displayId) const {
3993 if (windowHandleToken == nullptr) {
3994 return nullptr;
3995 }
3996
3997 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3998 if (windowHandle->getToken() == windowHandleToken) {
3999 return windowHandle;
4000 }
4001 }
4002 return nullptr;
4003}
4004
4005sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
4006 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4007 return getWindowHandleLocked(focusedToken, displayId);
4008}
4009
Mady Mellor017bcd12020-06-23 19:12:00 +00004010bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
4011 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004012 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00004013 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004014 if (handle->getId() == windowHandle->getId() &&
4015 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004016 if (windowHandle->getInfo()->displayId != it.first) {
4017 ALOGE("Found window %s in display %" PRId32
4018 ", but it should belong to display %" PRId32,
4019 windowHandle->getName().c_str(), it.first,
4020 windowHandle->getInfo()->displayId);
4021 }
4022 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08004023 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004024 }
4025 }
4026 return false;
4027}
4028
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004029bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
4030 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4031 const bool noInputChannel =
4032 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4033 if (connection != nullptr && noInputChannel) {
4034 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4035 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4036 return false;
4037 }
4038
4039 if (connection == nullptr) {
4040 if (!noInputChannel) {
4041 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4042 }
4043 return false;
4044 }
4045 if (!connection->responsive) {
4046 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4047 return false;
4048 }
4049 return true;
4050}
4051
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004052std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4053 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07004054 size_t count = mInputChannelsByToken.count(token);
4055 if (count == 0) {
4056 return nullptr;
4057 }
4058 return mInputChannelsByToken.at(token);
4059}
4060
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004061void InputDispatcher::updateWindowHandlesForDisplayLocked(
4062 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
4063 if (inputWindowHandles.empty()) {
4064 // Remove all handles on a display if there are no windows left.
4065 mWindowHandlesByDisplay.erase(displayId);
4066 return;
4067 }
4068
4069 // Since we compare the pointer of input window handles across window updates, we need
4070 // to make sure the handle object for the same window stays unchanged across updates.
4071 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07004072 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004073 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004074 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004075 }
4076
4077 std::vector<sp<InputWindowHandle>> newHandles;
4078 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
4079 if (!handle->updateInfo()) {
4080 // handle no longer valid
4081 continue;
4082 }
4083
4084 const InputWindowInfo* info = handle->getInfo();
4085 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4086 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4087 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01004088 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4089 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
4090 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004091 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004092 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004093 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004094 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004095 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004096 }
4097
4098 if (info->displayId != displayId) {
4099 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4100 handle->getName().c_str(), displayId, info->displayId);
4101 continue;
4102 }
4103
Robert Carredd13602020-04-13 17:24:34 -07004104 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4105 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004106 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004107 oldHandle->updateFrom(handle);
4108 newHandles.push_back(oldHandle);
4109 } else {
4110 newHandles.push_back(handle);
4111 }
4112 }
4113
4114 // Insert or replace
4115 mWindowHandlesByDisplay[displayId] = newHandles;
4116}
4117
Arthur Hung72d8dc32020-03-28 00:48:39 +00004118void InputDispatcher::setInputWindows(
4119 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4120 { // acquire lock
4121 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004122 for (const auto& [displayId, handles] : handlesPerDisplay) {
4123 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004124 }
4125 }
4126 // Wake up poll loop since it may need to make new input dispatching choices.
4127 mLooper->wake();
4128}
4129
Arthur Hungb92218b2018-08-14 12:00:21 +08004130/**
4131 * Called from InputManagerService, update window handle list by displayId that can receive input.
4132 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4133 * If set an empty list, remove all handles from the specific display.
4134 * For focused handle, check if need to change and send a cancel event to previous one.
4135 * For removed handle, check if need to send a cancel event if already in touch.
4136 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004137void InputDispatcher::setInputWindowsLocked(
4138 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004139 if (DEBUG_FOCUS) {
4140 std::string windowList;
4141 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4142 windowList += iwh->getName() + " ";
4143 }
4144 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4145 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004146
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004147 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4148 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4149 const bool noInputWindow =
4150 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4151 if (noInputWindow && window->getToken() != nullptr) {
4152 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4153 window->getName().c_str());
4154 window->releaseChannel();
4155 }
4156 }
4157
Arthur Hung72d8dc32020-03-28 00:48:39 +00004158 // Copy old handles for release if they are no longer present.
4159 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004160
Arthur Hung72d8dc32020-03-28 00:48:39 +00004161 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004162
Vishnu Nair958da932020-08-21 17:12:37 -07004163 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4164 if (mLastHoverWindowHandle &&
4165 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4166 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004167 mLastHoverWindowHandle = nullptr;
4168 }
4169
Vishnu Nair958da932020-08-21 17:12:37 -07004170 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4171 if (focusedToken) {
4172 FocusResult result = checkTokenFocusableLocked(focusedToken, displayId);
4173 if (result != FocusResult::OK) {
4174 onFocusChangedLocked(focusedToken, nullptr, displayId, typeToString(result));
4175 }
4176 }
4177
4178 std::optional<FocusRequest> focusRequest =
4179 getOptionalValueByKey(mPendingFocusRequests, displayId);
4180 if (focusRequest) {
4181 // If the window from the pending request is now visible, provide it focus.
4182 FocusResult result = handleFocusRequestLocked(*focusRequest);
4183 if (result != FocusResult::NOT_VISIBLE) {
4184 // Drop the request if we were able to change the focus or we cannot change
4185 // it for another reason.
4186 mPendingFocusRequests.erase(displayId);
4187 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004188 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004189
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004190 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4191 mTouchStatesByDisplay.find(displayId);
4192 if (stateIt != mTouchStatesByDisplay.end()) {
4193 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004194 for (size_t i = 0; i < state.windows.size();) {
4195 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004196 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004197 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004198 ALOGD("Touched window was removed: %s in display %" PRId32,
4199 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004200 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004201 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004202 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4203 if (touchedInputChannel != nullptr) {
4204 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4205 "touched window was removed");
4206 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004207 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004208 state.windows.erase(state.windows.begin() + i);
4209 } else {
4210 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004211 }
4212 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004213 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004214
Arthur Hung72d8dc32020-03-28 00:48:39 +00004215 // Release information for windows that are no longer present.
4216 // This ensures that unused input channels are released promptly.
4217 // Otherwise, they might stick around until the window handle is destroyed
4218 // which might not happen until the next GC.
4219 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004220 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004221 if (DEBUG_FOCUS) {
4222 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004223 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004224 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004225 // To avoid making too many calls into the compat framework, only
4226 // check for window flags when windows are going away.
4227 // TODO(b/157929241) : delete this. This is only needed temporarily
4228 // in order to gather some data about the flag usage
4229 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4230 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4231 oldWindowHandle->getName().c_str());
4232 if (mCompatService != nullptr) {
4233 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4234 oldWindowHandle->getInfo()->ownerUid);
4235 }
4236 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004237 }
chaviw291d88a2019-02-14 10:33:58 -08004238 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004239}
4240
4241void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004242 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004243 if (DEBUG_FOCUS) {
4244 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4245 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4246 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004247 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004248 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004249
Chris Yea209fde2020-07-22 13:54:51 -07004250 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004251 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004252
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004253 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4254 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004255 }
4256
Chris Yea209fde2020-07-22 13:54:51 -07004257 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004258 if (inputApplicationHandle != nullptr) {
4259 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4260 } else {
4261 mFocusedApplicationHandlesByDisplay.erase(displayId);
4262 }
4263
4264 // No matter what the old focused application was, stop waiting on it because it is
4265 // no longer focused.
4266 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004267 } // release lock
4268
4269 // Wake up poll loop since it may need to make new input dispatching choices.
4270 mLooper->wake();
4271}
4272
Tiger Huang721e26f2018-07-24 22:26:19 +08004273/**
4274 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4275 * the display not specified.
4276 *
4277 * We track any unreleased events for each window. If a window loses the ability to receive the
4278 * released event, we will send a cancel event to it. So when the focused display is changed, we
4279 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4280 * display. The display-specified events won't be affected.
4281 */
4282void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004283 if (DEBUG_FOCUS) {
4284 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4285 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004286 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004287 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004288
4289 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004290 sp<IBinder> oldFocusedWindowToken =
4291 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4292 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004293 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004294 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004295 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004296 CancelationOptions
4297 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4298 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004299 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004300 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4301 }
4302 }
4303 mFocusedDisplayId = displayId;
4304
Chris Ye3c2d6f52020-08-09 10:39:48 -07004305 // Find new focused window and validate
Vishnu Nairad321cd2020-08-20 16:40:21 -07004306 sp<IBinder> newFocusedWindowToken =
4307 getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4308 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004309
Vishnu Nairad321cd2020-08-20 16:40:21 -07004310 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004311 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004312 if (!mFocusedWindowTokenByDisplay.empty()) {
4313 ALOGE("But another display has a focused window\n%s",
4314 dumpFocusedWindowsLocked().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004315 }
4316 }
4317 }
4318
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004319 if (DEBUG_FOCUS) {
4320 logDispatchStateLocked();
4321 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004322 } // release lock
4323
4324 // Wake up poll loop since it may need to make new input dispatching choices.
4325 mLooper->wake();
4326}
4327
Michael Wrightd02c5b62014-02-10 15:10:22 -08004328void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004329 if (DEBUG_FOCUS) {
4330 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4331 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004332
4333 bool changed;
4334 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004335 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004336
4337 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4338 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004339 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004340 }
4341
4342 if (mDispatchEnabled && !enabled) {
4343 resetAndDropEverythingLocked("dispatcher is being disabled");
4344 }
4345
4346 mDispatchEnabled = enabled;
4347 mDispatchFrozen = frozen;
4348 changed = true;
4349 } else {
4350 changed = false;
4351 }
4352
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004353 if (DEBUG_FOCUS) {
4354 logDispatchStateLocked();
4355 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004356 } // release lock
4357
4358 if (changed) {
4359 // Wake up poll loop since it may need to make new input dispatching choices.
4360 mLooper->wake();
4361 }
4362}
4363
4364void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004365 if (DEBUG_FOCUS) {
4366 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4367 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004368
4369 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004370 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004371
4372 if (mInputFilterEnabled == enabled) {
4373 return;
4374 }
4375
4376 mInputFilterEnabled = enabled;
4377 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4378 } // release lock
4379
4380 // Wake up poll loop since there might be work to do to drop everything.
4381 mLooper->wake();
4382}
4383
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004384void InputDispatcher::setInTouchMode(bool inTouchMode) {
4385 std::scoped_lock lock(mLock);
4386 mInTouchMode = inTouchMode;
4387}
4388
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004389void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4390 if (opacity < 0 || opacity > 1) {
4391 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4392 return;
4393 }
4394
4395 std::scoped_lock lock(mLock);
4396 mMaximumObscuringOpacityForTouch = opacity;
4397}
4398
4399void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4400 std::scoped_lock lock(mLock);
4401 mBlockUntrustedTouchesMode = mode;
4402}
4403
chaviwfbe5d9c2018-12-26 12:23:37 -08004404bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4405 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004406 if (DEBUG_FOCUS) {
4407 ALOGD("Trivial transfer to same window.");
4408 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004409 return true;
4410 }
4411
Michael Wrightd02c5b62014-02-10 15:10:22 -08004412 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004413 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004414
chaviwfbe5d9c2018-12-26 12:23:37 -08004415 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4416 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004417 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004418 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004419 return false;
4420 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004421 if (DEBUG_FOCUS) {
4422 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4423 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4424 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004425 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004426 if (DEBUG_FOCUS) {
4427 ALOGD("Cannot transfer focus because windows are on different displays.");
4428 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004429 return false;
4430 }
4431
4432 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004433 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4434 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004435 for (size_t i = 0; i < state.windows.size(); i++) {
4436 const TouchedWindow& touchedWindow = state.windows[i];
4437 if (touchedWindow.windowHandle == fromWindowHandle) {
4438 int32_t oldTargetFlags = touchedWindow.targetFlags;
4439 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004440
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004441 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004442
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004443 int32_t newTargetFlags = oldTargetFlags &
4444 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4445 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004446 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004447
Jeff Brownf086ddb2014-02-11 14:28:48 -08004448 found = true;
4449 goto Found;
4450 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004451 }
4452 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004453 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004454
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004455 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004456 if (DEBUG_FOCUS) {
4457 ALOGD("Focus transfer failed because from window did not have focus.");
4458 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004459 return false;
4460 }
4461
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004462 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4463 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004464 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004465 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004466 CancelationOptions
4467 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4468 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004469 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004470 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004471 }
4472
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004473 if (DEBUG_FOCUS) {
4474 logDispatchStateLocked();
4475 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004476 } // release lock
4477
4478 // Wake up poll loop since it may need to make new input dispatching choices.
4479 mLooper->wake();
4480 return true;
4481}
4482
4483void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004484 if (DEBUG_FOCUS) {
4485 ALOGD("Resetting and dropping all events (%s).", reason);
4486 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004487
4488 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4489 synthesizeCancelationEventsForAllConnectionsLocked(options);
4490
4491 resetKeyRepeatLocked();
4492 releasePendingEventLocked();
4493 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004494 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004495
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004496 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004497 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004498 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004499 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004500}
4501
4502void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004503 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004504 dumpDispatchStateLocked(dump);
4505
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004506 std::istringstream stream(dump);
4507 std::string line;
4508
4509 while (std::getline(stream, line, '\n')) {
4510 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004511 }
4512}
4513
Vishnu Nairad321cd2020-08-20 16:40:21 -07004514std::string InputDispatcher::dumpFocusedWindowsLocked() {
4515 if (mFocusedWindowTokenByDisplay.empty()) {
4516 return INDENT "FocusedWindows: <none>\n";
4517 }
4518
4519 std::string dump;
4520 dump += INDENT "FocusedWindows:\n";
4521 for (auto& it : mFocusedWindowTokenByDisplay) {
4522 const int32_t displayId = it.first;
4523 const sp<InputWindowHandle> windowHandle = getFocusedWindowHandleLocked(displayId);
4524 if (windowHandle) {
4525 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
4526 windowHandle->getName().c_str());
4527 } else {
4528 dump += StringPrintf(INDENT2 "displayId=%" PRId32
4529 " has focused token without a window'\n",
4530 displayId);
4531 }
4532 }
4533 return dump;
4534}
4535
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004536std::string InputDispatcher::dumpPendingFocusRequestsLocked() {
4537 if (mPendingFocusRequests.empty()) {
4538 return INDENT "mPendingFocusRequests: <none>\n";
4539 }
4540
4541 std::string dump;
4542 dump += INDENT "mPendingFocusRequests:\n";
4543 for (const auto& [displayId, focusRequest] : mPendingFocusRequests) {
4544 // Rather than printing raw values for focusRequest.token and focusRequest.focusedToken,
4545 // try to resolve them to actual windows.
4546 std::string windowName = getConnectionNameLocked(focusRequest.token);
4547 std::string focusedWindowName = getConnectionNameLocked(focusRequest.focusedToken);
4548 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", token->%s, focusedToken->%s\n",
4549 displayId, windowName.c_str(), focusedWindowName.c_str());
4550 }
4551 return dump;
4552}
4553
Prabir Pradhan99987712020-11-10 18:43:05 -08004554std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4555 std::string dump;
4556
4557 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4558 toString(mFocusedWindowRequestedPointerCapture));
4559
4560 std::string windowName = "None";
4561 if (mWindowTokenWithPointerCapture) {
4562 const sp<InputWindowHandle> captureWindowHandle =
4563 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4564 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4565 : "token has capture without window";
4566 }
4567 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4568
4569 return dump;
4570}
4571
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004572void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004573 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4574 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4575 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004576 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004577
Tiger Huang721e26f2018-07-24 22:26:19 +08004578 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4579 dump += StringPrintf(INDENT "FocusedApplications:\n");
4580 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4581 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004582 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004583 const std::chrono::duration timeout =
4584 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004585 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004586 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004587 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004588 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004589 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004590 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004591 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004592
Vishnu Nairad321cd2020-08-20 16:40:21 -07004593 dump += dumpFocusedWindowsLocked();
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004594 dump += dumpPendingFocusRequestsLocked();
Prabir Pradhan99987712020-11-10 18:43:05 -08004595 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004596
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004597 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004598 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004599 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4600 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004601 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004602 state.displayId, toString(state.down), toString(state.split),
4603 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004604 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004605 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004606 for (size_t i = 0; i < state.windows.size(); i++) {
4607 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004608 dump += StringPrintf(INDENT4
4609 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4610 i, touchedWindow.windowHandle->getName().c_str(),
4611 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004612 }
4613 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004614 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004615 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004616 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004617 dump += INDENT3 "Portal windows:\n";
4618 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004619 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004620 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4621 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004622 }
4623 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004624 }
4625 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004626 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004627 }
4628
Arthur Hungb92218b2018-08-14 12:00:21 +08004629 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004630 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004631 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004632 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004633 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004634 dump += INDENT2 "Windows:\n";
4635 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004636 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004637 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004638
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004639 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004640 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004641 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004642 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004643 "frame=[%d,%d][%d,%d], globalScale=%f, "
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004644 "applicationInfo=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004645 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004646 i, windowInfo->name.c_str(), windowInfo->id,
4647 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004648 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004649 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004650 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004651 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004652 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004653 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004654 windowInfo->frameLeft, windowInfo->frameTop,
4655 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004656 windowInfo->globalScaleFactor,
4657 windowInfo->applicationInfo.name.c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004658 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004659 dump += StringPrintf(", inputFeatures=%s",
4660 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004661 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004662 "ms, trustedOverlay=%s, hasToken=%s, "
4663 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004664 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004665 millis(windowInfo->dispatchingTimeout),
4666 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004667 toString(windowInfo->token != nullptr),
4668 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004669 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004670 }
4671 } else {
4672 dump += INDENT2 "Windows: <none>\n";
4673 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004674 }
4675 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004676 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004677 }
4678
Michael Wright3dd60e22019-03-27 22:06:44 +00004679 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004680 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004681 const std::vector<Monitor>& monitors = it.second;
4682 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4683 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004684 }
4685 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004686 const std::vector<Monitor>& monitors = it.second;
4687 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4688 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004689 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004690 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004691 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004692 }
4693
4694 nsecs_t currentTime = now();
4695
4696 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004697 if (!mRecentQueue.empty()) {
4698 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004699 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004700 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004701 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004702 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004703 }
4704 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004705 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004706 }
4707
4708 // Dump event currently being dispatched.
4709 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004710 dump += INDENT "PendingEvent:\n";
4711 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004712 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004713 dump += StringPrintf(", age=%" PRId64 "ms\n",
4714 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004715 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004716 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004717 }
4718
4719 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004720 if (!mInboundQueue.empty()) {
4721 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004722 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004723 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004724 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004725 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004726 }
4727 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004728 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004729 }
4730
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004731 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004732 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004733 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4734 const KeyReplacement& replacement = pair.first;
4735 int32_t newKeyCode = pair.second;
4736 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004737 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004738 }
4739 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004740 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004741 }
4742
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004743 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004744 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004745 for (const auto& pair : mConnectionsByFd) {
4746 const sp<Connection>& connection = pair.second;
4747 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004748 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004749 pair.first, connection->getInputChannelName().c_str(),
4750 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004751 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004752
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004753 if (!connection->outboundQueue.empty()) {
4754 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4755 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004756 dump += dumpQueue(connection->outboundQueue, currentTime);
4757
Michael Wrightd02c5b62014-02-10 15:10:22 -08004758 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004759 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004760 }
4761
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004762 if (!connection->waitQueue.empty()) {
4763 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4764 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004765 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004766 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004767 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004768 }
4769 }
4770 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004771 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004772 }
4773
4774 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004775 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4776 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004777 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004778 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004779 }
4780
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004781 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004782 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4783 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4784 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004785}
4786
Michael Wright3dd60e22019-03-27 22:06:44 +00004787void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4788 const size_t numMonitors = monitors.size();
4789 for (size_t i = 0; i < numMonitors; i++) {
4790 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004791 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004792 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4793 dump += "\n";
4794 }
4795}
4796
Garfield Tan15601662020-09-22 15:32:38 -07004797base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4798 const std::string& name) {
4799#if DEBUG_CHANNEL_CREATION
4800 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004801#endif
4802
Garfield Tan15601662020-09-22 15:32:38 -07004803 std::shared_ptr<InputChannel> serverChannel;
4804 std::unique_ptr<InputChannel> clientChannel;
4805 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4806
4807 if (result) {
4808 return base::Error(result) << "Failed to open input channel pair with name " << name;
4809 }
4810
Michael Wrightd02c5b62014-02-10 15:10:22 -08004811 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004812 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004813 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004814
Garfield Tan15601662020-09-22 15:32:38 -07004815 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004816 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004817 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004818
Michael Wrightd02c5b62014-02-10 15:10:22 -08004819 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4820 } // release lock
4821
4822 // Wake the looper because some connections have changed.
4823 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004824 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004825}
4826
Garfield Tan15601662020-09-22 15:32:38 -07004827base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
4828 int32_t displayId, bool isGestureMonitor, const std::string& name) {
4829 std::shared_ptr<InputChannel> serverChannel;
4830 std::unique_ptr<InputChannel> clientChannel;
4831 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4832 if (result) {
4833 return base::Error(result) << "Failed to open input channel pair with name " << name;
4834 }
4835
Michael Wright3dd60e22019-03-27 22:06:44 +00004836 { // acquire lock
4837 std::scoped_lock _l(mLock);
4838
4839 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004840 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4841 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004842 }
4843
Garfield Tan15601662020-09-22 15:32:38 -07004844 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004845
Garfield Tan15601662020-09-22 15:32:38 -07004846 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004847 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004848 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004849
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004850 auto& monitorsByDisplay =
4851 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Garfield Tan15601662020-09-22 15:32:38 -07004852 monitorsByDisplay[displayId].emplace_back(serverChannel);
Michael Wright3dd60e22019-03-27 22:06:44 +00004853
4854 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004855 }
Garfield Tan15601662020-09-22 15:32:38 -07004856
Michael Wright3dd60e22019-03-27 22:06:44 +00004857 // Wake the looper because some connections have changed.
4858 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004859 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004860}
4861
Garfield Tan15601662020-09-22 15:32:38 -07004862status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004863 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004864 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004865
Garfield Tan15601662020-09-22 15:32:38 -07004866 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004867 if (status) {
4868 return status;
4869 }
4870 } // release lock
4871
4872 // Wake the poll loop because removing the connection may have changed the current
4873 // synchronization state.
4874 mLooper->wake();
4875 return OK;
4876}
4877
Garfield Tan15601662020-09-22 15:32:38 -07004878status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
4879 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004880 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004881 if (connection == nullptr) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004882 ALOGW("Attempted to unregister already unregistered input channel");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004883 return BAD_VALUE;
4884 }
4885
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004886 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004887 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07004888
Michael Wrightd02c5b62014-02-10 15:10:22 -08004889 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004890 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004891 }
4892
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004893 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004894
4895 nsecs_t currentTime = now();
4896 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4897
4898 connection->status = Connection::STATUS_ZOMBIE;
4899 return OK;
4900}
4901
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004902void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
4903 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
4904 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00004905}
4906
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004907void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004908 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00004909 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004910 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004911 std::vector<Monitor>& monitors = it->second;
4912 const size_t numMonitors = monitors.size();
4913 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004914 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004915 monitors.erase(monitors.begin() + i);
4916 break;
4917 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004918 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004919 if (monitors.empty()) {
4920 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004921 } else {
4922 ++it;
4923 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004924 }
4925}
4926
Michael Wright3dd60e22019-03-27 22:06:44 +00004927status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4928 { // acquire lock
4929 std::scoped_lock _l(mLock);
4930 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4931
4932 if (!foundDisplayId) {
4933 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4934 return BAD_VALUE;
4935 }
4936 int32_t displayId = foundDisplayId.value();
4937
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004938 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4939 mTouchStatesByDisplay.find(displayId);
4940 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004941 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4942 return BAD_VALUE;
4943 }
4944
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004945 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00004946 std::optional<int32_t> foundDeviceId;
4947 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004948 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004949 foundDeviceId = state.deviceId;
4950 }
4951 }
4952 if (!foundDeviceId || !state.down) {
4953 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004954 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004955 return BAD_VALUE;
4956 }
4957 int32_t deviceId = foundDeviceId.value();
4958
4959 // Send cancel events to all the input channels we're stealing from.
4960 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004961 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004962 options.deviceId = deviceId;
4963 options.displayId = displayId;
4964 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004965 std::shared_ptr<InputChannel> channel =
4966 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004967 if (channel != nullptr) {
4968 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4969 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004970 }
4971 // Then clear the current touch state so we stop dispatching to them as well.
4972 state.filterNonMonitors();
4973 }
4974 return OK;
4975}
4976
Prabir Pradhan99987712020-11-10 18:43:05 -08004977void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
4978 { // acquire lock
4979 std::scoped_lock _l(mLock);
4980 if (DEBUG_FOCUS) {
4981 const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
4982 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
4983 windowHandle != nullptr ? windowHandle->getName().c_str()
4984 : "token without window");
4985 }
4986
4987 const sp<IBinder> focusedToken =
4988 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4989 if (focusedToken != windowToken) {
4990 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
4991 enabled ? "enable" : "disable");
4992 return;
4993 }
4994
4995 if (enabled == mFocusedWindowRequestedPointerCapture) {
4996 ALOGW("Ignoring request to %s Pointer Capture: "
4997 "window has %s requested pointer capture.",
4998 enabled ? "enable" : "disable", enabled ? "already" : "not");
4999 return;
5000 }
5001
5002 mFocusedWindowRequestedPointerCapture = enabled;
5003 setPointerCaptureLocked(enabled);
5004 } // release lock
5005
5006 // Wake the thread to process command entries.
5007 mLooper->wake();
5008}
5009
Michael Wright3dd60e22019-03-27 22:06:44 +00005010std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5011 const sp<IBinder>& token) {
5012 for (const auto& it : mGestureMonitorsByDisplay) {
5013 const std::vector<Monitor>& monitors = it.second;
5014 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005015 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005016 return it.first;
5017 }
5018 }
5019 }
5020 return std::nullopt;
5021}
5022
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005023sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005024 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005025 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005026 }
5027
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005028 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005029 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005030 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005031 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005032 }
5033 }
Robert Carr4e670e52018-08-15 13:26:12 -07005034
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005035 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005036}
5037
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005038std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5039 sp<Connection> connection = getConnectionLocked(connectionToken);
5040 if (connection == nullptr) {
5041 return "<nullptr>";
5042 }
5043 return connection->getInputChannelName();
5044}
5045
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005046void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005047 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005048 removeByValue(mConnectionsByFd, connection);
5049}
5050
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005051void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5052 const sp<Connection>& connection, uint32_t seq,
5053 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005054 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5055 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005056 commandEntry->connection = connection;
5057 commandEntry->eventTime = currentTime;
5058 commandEntry->seq = seq;
5059 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005060 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005061}
5062
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005063void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5064 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005065 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005066 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005067
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005068 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5069 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005070 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005071 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005072}
5073
Vishnu Nairad321cd2020-08-20 16:40:21 -07005074void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5075 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005076 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5077 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005078 commandEntry->oldToken = oldToken;
5079 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005080 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005081}
5082
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005083void InputDispatcher::onAnrLocked(const Connection& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005084 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5085 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005086 if (connection.waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005087 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005088 connection.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005089 return;
5090 }
5091 /**
5092 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5093 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5094 * has changed. This could cause newer entries to time out before the already dispatched
5095 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5096 * processes the events linearly. So providing information about the oldest entry seems to be
5097 * most useful.
5098 */
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005099 DispatchEntry* oldestEntry = *connection.waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005100 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5101 std::string reason =
5102 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005103 connection.inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005104 ns2ms(currentWait),
5105 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005106 sp<IBinder> connectionToken = connection.inputChannel->getConnectionToken();
5107 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005108
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005109 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5110 &InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible);
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005111 commandEntry->connectionToken = connectionToken;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005112 commandEntry->reason = std::move(reason);
5113 postCommandLocked(std::move(commandEntry));
5114}
5115
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005116void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5117 std::string reason =
5118 StringPrintf("%s does not have a focused window", application->getName().c_str());
5119 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005120
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005121 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5122 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5123 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005124 postCommandLocked(std::move(commandEntry));
5125}
5126
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005127void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5128 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5129 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5130 commandEntry->obscuringPackage = obscuringPackage;
5131 postCommandLocked(std::move(commandEntry));
5132}
5133
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005134void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
5135 const std::string& reason) {
5136 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5137 updateLastAnrStateLocked(windowLabel, reason);
5138}
5139
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005140void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5141 const std::string& reason) {
5142 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005143 updateLastAnrStateLocked(windowLabel, reason);
5144}
5145
5146void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5147 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005148 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005149 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005150 struct tm tm;
5151 localtime_r(&t, &tm);
5152 char timestr[64];
5153 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005154 mLastAnrState.clear();
5155 mLastAnrState += INDENT "ANR:\n";
5156 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005157 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5158 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005159 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005160}
5161
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005162void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005163 mLock.unlock();
5164
5165 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5166
5167 mLock.lock();
5168}
5169
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005170void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005171 sp<Connection> connection = commandEntry->connection;
5172
5173 if (connection->status != Connection::STATUS_ZOMBIE) {
5174 mLock.unlock();
5175
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005176 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005177
5178 mLock.lock();
5179 }
5180}
5181
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005182void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005183 sp<IBinder> oldToken = commandEntry->oldToken;
5184 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005185 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005186 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005187 mLock.lock();
5188}
5189
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005190void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005191 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005192
5193 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5194
5195 mLock.lock();
5196}
5197
5198void InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible(
5199 CommandEntry* commandEntry) {
5200 mLock.unlock();
5201
5202 mPolicy->notifyConnectionUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005203
5204 mLock.lock();
5205
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005206 // stop waking up for events in this connection, it is already not responding
5207 sp<Connection> connection = getConnectionLocked(commandEntry->connectionToken);
5208 if (connection == nullptr) {
5209 return;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005210 }
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005211 cancelEventsForAnrLocked(connection);
5212}
5213
5214void InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5215 mLock.unlock();
5216
5217 mPolicy->notifyConnectionResponsive(commandEntry->connectionToken);
5218
5219 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005220}
5221
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005222void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5223 mLock.unlock();
5224
5225 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5226
5227 mLock.lock();
5228}
5229
Michael Wrightd02c5b62014-02-10 15:10:22 -08005230void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5231 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005232 KeyEntry& entry = *(commandEntry->keyEntry);
5233 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005234
5235 mLock.unlock();
5236
Michael Wright2b3c3302018-03-02 17:19:13 +00005237 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005238 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005239 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005240 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5241 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005242 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005243 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005244
5245 mLock.lock();
5246
5247 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005248 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005249 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005250 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005251 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005252 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5253 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005254 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005255}
5256
chaviwfd6d3512019-03-25 13:23:49 -07005257void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5258 mLock.unlock();
5259 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5260 mLock.lock();
5261}
5262
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005263/**
5264 * Connection is responsive if it has no events in the waitQueue that are older than the
5265 * current time.
5266 */
5267static bool isConnectionResponsive(const Connection& connection) {
5268 const nsecs_t currentTime = now();
5269 for (const DispatchEntry* entry : connection.waitQueue) {
5270 if (entry->timeoutTime < currentTime) {
5271 return false;
5272 }
5273 }
5274 return true;
5275}
5276
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005277void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005278 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005279 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005280 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005281 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005282
5283 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005284 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005285 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005286 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005287 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005288 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005289 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005290 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005291 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5292 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005293 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005294 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005295
5296 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005297 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005298 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005299 restartEvent =
5300 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005301 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005302 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005303 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5304 handled);
5305 } else {
5306 restartEvent = false;
5307 }
5308
5309 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005310 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005311 // contents of the wait queue to have been drained, so we need to double-check
5312 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005313 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5314 if (dispatchEntryIt != connection->waitQueue.end()) {
5315 dispatchEntry = *dispatchEntryIt;
5316 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005317 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5318 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005319 if (!connection->responsive) {
5320 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005321 if (connection->responsive) {
5322 // The connection was unresponsive, and now it's responsive. Tell the policy
5323 // about it so that it can stop ANR.
5324 std::unique_ptr<CommandEntry> connectionResponsiveCommand =
5325 std::make_unique<CommandEntry>(
5326 &InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible);
5327 connectionResponsiveCommand->connectionToken = connectionToken;
5328 postCommandLocked(std::move(connectionResponsiveCommand));
5329 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005330 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005331 traceWaitQueueLength(connection);
5332 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005333 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005334 traceOutboundQueueLength(connection);
5335 } else {
5336 releaseDispatchEntry(dispatchEntry);
5337 }
5338 }
5339
5340 // Start the next dispatch cycle for this connection.
5341 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005342}
5343
5344bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005345 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005346 KeyEntry& keyEntry, bool handled) {
5347 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005348 if (!handled) {
5349 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005350 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005351 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005352 return false;
5353 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005354
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005355 // Get the fallback key state.
5356 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005357 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005358 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005359 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005360 connection->inputState.removeFallbackKey(originalKeyCode);
5361 }
5362
5363 if (handled || !dispatchEntry->hasForegroundTarget()) {
5364 // If the application handles the original key for which we previously
5365 // generated a fallback or if the window is not a foreground window,
5366 // then cancel the associated fallback key, if any.
5367 if (fallbackKeyCode != -1) {
5368 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005369#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005370 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005371 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005372 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005373#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005374 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005375 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005376
5377 mLock.unlock();
5378
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005379 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005380 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005381
5382 mLock.lock();
5383
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005384 // Cancel the fallback key.
5385 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005386 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005387 "application handled the original non-fallback key "
5388 "or is no longer a foreground target, "
5389 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005390 options.keyCode = fallbackKeyCode;
5391 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005392 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005393 connection->inputState.removeFallbackKey(originalKeyCode);
5394 }
5395 } else {
5396 // If the application did not handle a non-fallback key, first check
5397 // that we are in a good state to perform unhandled key event processing
5398 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005399 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005400 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005401#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005402 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005403 "since this is not an initial down. "
5404 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005405 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005406#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005407 return false;
5408 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005409
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005410 // Dispatch the unhandled key to the policy.
5411#if DEBUG_OUTBOUND_EVENT_DETAILS
5412 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005413 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005414 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005415#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005416 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005417
5418 mLock.unlock();
5419
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005420 bool fallback =
5421 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005422 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005423
5424 mLock.lock();
5425
5426 if (connection->status != Connection::STATUS_NORMAL) {
5427 connection->inputState.removeFallbackKey(originalKeyCode);
5428 return false;
5429 }
5430
5431 // Latch the fallback keycode for this key on an initial down.
5432 // The fallback keycode cannot change at any other point in the lifecycle.
5433 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005434 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005435 fallbackKeyCode = event.getKeyCode();
5436 } else {
5437 fallbackKeyCode = AKEYCODE_UNKNOWN;
5438 }
5439 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5440 }
5441
5442 ALOG_ASSERT(fallbackKeyCode != -1);
5443
5444 // Cancel the fallback key if the policy decides not to send it anymore.
5445 // We will continue to dispatch the key to the policy but we will no
5446 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005447 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5448 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005449#if DEBUG_OUTBOUND_EVENT_DETAILS
5450 if (fallback) {
5451 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005452 "as a fallback for %d, but on the DOWN it had requested "
5453 "to send %d instead. Fallback canceled.",
5454 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005455 } else {
5456 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005457 "but on the DOWN it had requested to send %d. "
5458 "Fallback canceled.",
5459 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005460 }
5461#endif
5462
5463 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5464 "canceling fallback, policy no longer desires it");
5465 options.keyCode = fallbackKeyCode;
5466 synthesizeCancelationEventsForConnectionLocked(connection, options);
5467
5468 fallback = false;
5469 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005470 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005471 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005472 }
5473 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005474
5475#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005476 {
5477 std::string msg;
5478 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5479 connection->inputState.getFallbackKeys();
5480 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005481 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005482 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005483 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005484 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005485 }
5486#endif
5487
5488 if (fallback) {
5489 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005490 keyEntry.eventTime = event.getEventTime();
5491 keyEntry.deviceId = event.getDeviceId();
5492 keyEntry.source = event.getSource();
5493 keyEntry.displayId = event.getDisplayId();
5494 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5495 keyEntry.keyCode = fallbackKeyCode;
5496 keyEntry.scanCode = event.getScanCode();
5497 keyEntry.metaState = event.getMetaState();
5498 keyEntry.repeatCount = event.getRepeatCount();
5499 keyEntry.downTime = event.getDownTime();
5500 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005501
5502#if DEBUG_OUTBOUND_EVENT_DETAILS
5503 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005504 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005505 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005506#endif
5507 return true; // restart the event
5508 } else {
5509#if DEBUG_OUTBOUND_EVENT_DETAILS
5510 ALOGD("Unhandled key event: No fallback key.");
5511#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005512
5513 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005514 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005515 }
5516 }
5517 return false;
5518}
5519
5520bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005521 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005522 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005523 return false;
5524}
5525
5526void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5527 mLock.unlock();
5528
5529 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5530
5531 mLock.lock();
5532}
5533
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005534KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
5535 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08005536 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08005537 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
5538 entry.repeatCount, entry.downTime, entry.eventTime);
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005539 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005540}
5541
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005542void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5543 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005544 // TODO Write some statistics about how long we spend waiting.
5545}
5546
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005547/**
5548 * Report the touch event latency to the statsd server.
5549 * Input events are reported for statistics if:
5550 * - This is a touchscreen event
5551 * - InputFilter is not enabled
5552 * - Event is not injected or synthesized
5553 *
5554 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5555 * from getting aggregated with the "old" data.
5556 */
5557void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5558 REQUIRES(mLock) {
5559 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5560 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5561 if (!reportForStatistics) {
5562 return;
5563 }
5564
5565 if (mTouchStatistics.shouldReport()) {
5566 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5567 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5568 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5569 mTouchStatistics.reset();
5570 }
5571 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5572 mTouchStatistics.addValue(latencyMicros);
5573}
5574
Michael Wrightd02c5b62014-02-10 15:10:22 -08005575void InputDispatcher::traceInboundQueueLengthLocked() {
5576 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005577 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005578 }
5579}
5580
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005581void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005582 if (ATRACE_ENABLED()) {
5583 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005584 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005585 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005586 }
5587}
5588
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005589void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005590 if (ATRACE_ENABLED()) {
5591 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005592 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005593 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005594 }
5595}
5596
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005597void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005598 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005599
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005600 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005601 dumpDispatchStateLocked(dump);
5602
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005603 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005604 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005605 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005606 }
5607}
5608
5609void InputDispatcher::monitor() {
5610 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005611 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005612 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005613 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005614}
5615
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005616/**
5617 * Wake up the dispatcher and wait until it processes all events and commands.
5618 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5619 * this method can be safely called from any thread, as long as you've ensured that
5620 * the work you are interested in completing has already been queued.
5621 */
5622bool InputDispatcher::waitForIdle() {
5623 /**
5624 * Timeout should represent the longest possible time that a device might spend processing
5625 * events and commands.
5626 */
5627 constexpr std::chrono::duration TIMEOUT = 100ms;
5628 std::unique_lock lock(mLock);
5629 mLooper->wake();
5630 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5631 return result == std::cv_status::no_timeout;
5632}
5633
Vishnu Naire798b472020-07-23 13:52:21 -07005634/**
5635 * Sets focus to the window identified by the token. This must be called
5636 * after updating any input window handles.
5637 *
5638 * Params:
5639 * request.token - input channel token used to identify the window that should gain focus.
5640 * request.focusedToken - the token that the caller expects currently to be focused. If the
5641 * specified token does not match the currently focused window, this request will be dropped.
5642 * If the specified focused token matches the currently focused window, the call will succeed.
5643 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5644 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5645 * when requesting the focus change. This determines which request gets
5646 * precedence if there is a focus change request from another source such as pointer down.
5647 */
Vishnu Nair958da932020-08-21 17:12:37 -07005648void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5649 { // acquire lock
5650 std::scoped_lock _l(mLock);
5651
5652 const int32_t displayId = request.displayId;
5653 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5654 if (request.focusedToken && oldFocusedToken != request.focusedToken) {
5655 ALOGD_IF(DEBUG_FOCUS,
5656 "setFocusedWindow on display %" PRId32
5657 " ignored, reason: focusedToken is not focused",
5658 displayId);
5659 return;
5660 }
5661
5662 mPendingFocusRequests.erase(displayId);
5663 FocusResult result = handleFocusRequestLocked(request);
5664 if (result == FocusResult::NOT_VISIBLE) {
5665 // The requested window is not currently visible. Wait for the window to become visible
5666 // and then provide it focus. This is to handle situations where a user action triggers
5667 // a new window to appear. We want to be able to queue any key events after the user
5668 // action and deliver it to the newly focused window. In order for this to happen, we
5669 // take focus from the currently focused window so key events can be queued.
5670 ALOGD_IF(DEBUG_FOCUS,
5671 "setFocusedWindow on display %" PRId32
5672 " pending, reason: window is not visible",
5673 displayId);
5674 mPendingFocusRequests[displayId] = request;
5675 onFocusChangedLocked(oldFocusedToken, nullptr, displayId,
5676 "setFocusedWindow_AwaitingWindowVisibility");
5677 } else if (result != FocusResult::OK) {
5678 ALOGW("setFocusedWindow on display %" PRId32 " ignored, reason:%s", displayId,
5679 typeToString(result));
5680 }
5681 } // release lock
5682 // Wake up poll loop since it may need to make new input dispatching choices.
5683 mLooper->wake();
5684}
5685
5686InputDispatcher::FocusResult InputDispatcher::handleFocusRequestLocked(
5687 const FocusRequest& request) {
5688 const int32_t displayId = request.displayId;
5689 const sp<IBinder> newFocusedToken = request.token;
5690 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5691
5692 if (oldFocusedToken == request.token) {
5693 ALOGD_IF(DEBUG_FOCUS,
5694 "setFocusedWindow on display %" PRId32 " ignored, reason: already focused",
5695 displayId);
5696 return FocusResult::OK;
5697 }
5698
5699 FocusResult result = checkTokenFocusableLocked(newFocusedToken, displayId);
5700 if (result != FocusResult::OK) {
5701 return result;
5702 }
5703
5704 std::string_view reason =
5705 (request.focusedToken) ? "setFocusedWindow_FocusCheck" : "setFocusedWindow";
5706 onFocusChangedLocked(oldFocusedToken, newFocusedToken, displayId, reason);
5707 return FocusResult::OK;
5708}
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005709
Vishnu Nairad321cd2020-08-20 16:40:21 -07005710void InputDispatcher::onFocusChangedLocked(const sp<IBinder>& oldFocusedToken,
5711 const sp<IBinder>& newFocusedToken, int32_t displayId,
5712 std::string_view reason) {
5713 if (oldFocusedToken) {
5714 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(oldFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005715 if (focusedInputChannel) {
5716 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5717 "focus left window");
5718 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005719 enqueueFocusEventLocked(oldFocusedToken, false /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005720 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005721 mFocusedWindowTokenByDisplay.erase(displayId);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005722 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005723 if (newFocusedToken) {
5724 mFocusedWindowTokenByDisplay[displayId] = newFocusedToken;
5725 enqueueFocusEventLocked(newFocusedToken, true /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005726 }
5727
Prabir Pradhan99987712020-11-10 18:43:05 -08005728 // If a window has pointer capture, then it must have focus. We need to ensure that this
5729 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
5730 // If the window loses focus before it loses pointer capture, then the window can be in a state
5731 // where it has pointer capture but not focus, violating the contract. Therefore we must
5732 // dispatch the pointer capture event before the focus event. Since focus events are added to
5733 // the front of the queue (above), we add the pointer capture event to the front of the queue
5734 // after the focus events are added. This ensures the pointer capture event ends up at the
5735 // front.
5736 disablePointerCaptureForcedLocked();
5737
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005738 if (mFocusedDisplayId == displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005739 notifyFocusChangedLocked(oldFocusedToken, newFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005740 }
5741}
Vishnu Nair958da932020-08-21 17:12:37 -07005742
Prabir Pradhan99987712020-11-10 18:43:05 -08005743void InputDispatcher::disablePointerCaptureForcedLocked() {
5744 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
5745 return;
5746 }
5747
5748 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
5749
5750 if (mFocusedWindowRequestedPointerCapture) {
5751 mFocusedWindowRequestedPointerCapture = false;
5752 setPointerCaptureLocked(false);
5753 }
5754
5755 if (!mWindowTokenWithPointerCapture) {
5756 // No need to send capture changes because no window has capture.
5757 return;
5758 }
5759
5760 if (mPendingEvent != nullptr) {
5761 // Move the pending event to the front of the queue. This will give the chance
5762 // for the pending event to be dropped if it is a captured event.
5763 mInboundQueue.push_front(mPendingEvent);
5764 mPendingEvent = nullptr;
5765 }
5766
5767 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
5768 false /* hasCapture */);
5769 mInboundQueue.push_front(std::move(entry));
5770}
5771
Vishnu Nair958da932020-08-21 17:12:37 -07005772/**
5773 * Checks if the window token can be focused on a display. The token can be focused if there is
5774 * at least one window handle that is visible with the same token and all window handles with the
5775 * same token are focusable.
5776 *
5777 * In the case of mirroring, two windows may share the same window token and their visibility
5778 * might be different. Example, the mirrored window can cover the window its mirroring. However,
5779 * we expect the focusability of the windows to match since its hard to reason why one window can
5780 * receive focus events and the other cannot when both are backed by the same input channel.
5781 */
5782InputDispatcher::FocusResult InputDispatcher::checkTokenFocusableLocked(const sp<IBinder>& token,
5783 int32_t displayId) const {
5784 bool allWindowsAreFocusable = true;
5785 bool visibleWindowFound = false;
5786 bool windowFound = false;
5787 for (const sp<InputWindowHandle>& window : getWindowHandlesLocked(displayId)) {
5788 if (window->getToken() != token) {
5789 continue;
5790 }
5791 windowFound = true;
5792 if (window->getInfo()->visible) {
5793 // Check if at least a single window is visible.
5794 visibleWindowFound = true;
5795 }
5796 if (!window->getInfo()->focusable) {
5797 // Check if all windows with the window token are focusable.
5798 allWindowsAreFocusable = false;
5799 break;
5800 }
5801 }
5802
5803 if (!windowFound) {
5804 return FocusResult::NO_WINDOW;
5805 }
5806 if (!allWindowsAreFocusable) {
5807 return FocusResult::NOT_FOCUSABLE;
5808 }
5809 if (!visibleWindowFound) {
5810 return FocusResult::NOT_VISIBLE;
5811 }
5812
5813 return FocusResult::OK;
5814}
Prabir Pradhan99987712020-11-10 18:43:05 -08005815
5816void InputDispatcher::setPointerCaptureLocked(bool enabled) {
5817 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5818 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
5819 commandEntry->enabled = enabled;
5820 postCommandLocked(std::move(commandEntry));
5821}
5822
5823void InputDispatcher::doSetPointerCaptureLockedInterruptible(
5824 android::inputdispatcher::CommandEntry* commandEntry) {
5825 mLock.unlock();
5826
5827 mPolicy->setPointerCapture(commandEntry->enabled);
5828
5829 mLock.lock();
5830}
5831
Garfield Tane84e6f92019-08-29 17:28:41 -07005832} // namespace android::inputdispatcher