blob: 13627513f0fc1323c2be9353429d37ef1ec8bf50 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
Garfield Tan15601662020-09-22 15:32:38 -070031// Log debug messages about channel creation
32#define DEBUG_CHANNEL_CREATION 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080033
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
Siarhei Vishniakou86587282019-09-09 18:20:15 +010038static constexpr bool DEBUG_FOCUS = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -080039
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +000040// Log debug messages about touch occlusion
41// STOPSHIP(b/169067926): Set to false
42static constexpr bool DEBUG_TOUCH_OCCLUSION = true;
43
Michael Wrightd02c5b62014-02-10 15:10:22 -080044// Log debug messages about the app switch latency optimization.
45#define DEBUG_APP_SWITCH 0
46
47// Log debug messages about hover events.
48#define DEBUG_HOVER 0
49
50#include "InputDispatcher.h"
51
Michael Wright2b3c3302018-03-02 17:19:13 +000052#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080053#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050054#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070055#include <binder/Binder.h>
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100056#include <binder/IServiceManager.h>
57#include <com/android/internal/compat/IPlatformCompatNative.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080058#include <input/InputDevice.h>
Michael Wright44753b12020-07-08 13:48:11 +010059#include <input/InputWindow.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070060#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000061#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070062#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010063#include <statslog.h>
64#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070065#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080066
Michael Wright44753b12020-07-08 13:48:11 +010067#include <cerrno>
68#include <cinttypes>
69#include <climits>
70#include <cstddef>
71#include <ctime>
72#include <queue>
73#include <sstream>
74
75#include "Connection.h"
76
Michael Wrightd02c5b62014-02-10 15:10:22 -080077#define INDENT " "
78#define INDENT2 " "
79#define INDENT3 " "
80#define INDENT4 " "
81
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080082using android::base::StringPrintf;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080083using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100084using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080085using android::os::InputEventInjectionResult;
86using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100087using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080088
Garfield Tane84e6f92019-08-29 17:28:41 -070089namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080090
91// Default input dispatching timeout if there is no focused application or paused window
92// from which to determine an appropriate dispatching timeout.
Siarhei Vishniakou70622952020-07-30 11:17:23 -050093constexpr std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT =
94 std::chrono::milliseconds(android::os::IInputConstants::DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
Michael Wrightd02c5b62014-02-10 15:10:22 -080095
96// Amount of time to allow for all pending events to be processed when an app switch
97// key is on the way. This is used to preempt input dispatch and drop input events
98// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000099constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800100
101// Amount of time to allow for an event to be dispatched (measured since its eventTime)
102// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000103constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104
Michael Wrightd02c5b62014-02-10 15:10:22 -0800105// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +0000106constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
107
108// Log a warning when an interception call takes longer than this to process.
109constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800110
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700111// Additional key latency in case a connection is still processing some motion events.
112// This will help with the case when a user touched a button that opens a new window,
113// and gives us the chance to dispatch the key to this new window.
114constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
115
Michael Wrightd02c5b62014-02-10 15:10:22 -0800116// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000117constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
118
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000119// Event log tags. See EventLogTags.logtags for reference
120constexpr int LOGTAG_INPUT_INTERACTION = 62000;
121constexpr int LOGTAG_INPUT_FOCUS = 62001;
122
Michael Wrightd02c5b62014-02-10 15:10:22 -0800123static inline nsecs_t now() {
124 return systemTime(SYSTEM_TIME_MONOTONIC);
125}
126
127static inline const char* toString(bool value) {
128 return value ? "true" : "false";
129}
130
131static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700132 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
133 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800134}
135
136static bool isValidKeyAction(int32_t action) {
137 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700138 case AKEY_EVENT_ACTION_DOWN:
139 case AKEY_EVENT_ACTION_UP:
140 return true;
141 default:
142 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800143 }
144}
145
146static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700147 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800148 ALOGE("Key event has invalid action code 0x%x", action);
149 return false;
150 }
151 return true;
152}
153
Michael Wright7b159c92015-05-14 14:48:03 +0100154static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800155 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700156 case AMOTION_EVENT_ACTION_DOWN:
157 case AMOTION_EVENT_ACTION_UP:
158 case AMOTION_EVENT_ACTION_CANCEL:
159 case AMOTION_EVENT_ACTION_MOVE:
160 case AMOTION_EVENT_ACTION_OUTSIDE:
161 case AMOTION_EVENT_ACTION_HOVER_ENTER:
162 case AMOTION_EVENT_ACTION_HOVER_MOVE:
163 case AMOTION_EVENT_ACTION_HOVER_EXIT:
164 case AMOTION_EVENT_ACTION_SCROLL:
165 return true;
166 case AMOTION_EVENT_ACTION_POINTER_DOWN:
167 case AMOTION_EVENT_ACTION_POINTER_UP: {
168 int32_t index = getMotionEventActionPointerIndex(action);
169 return index >= 0 && index < pointerCount;
170 }
171 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
172 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
173 return actionButton != 0;
174 default:
175 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800176 }
177}
178
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500179static int64_t millis(std::chrono::nanoseconds t) {
180 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
181}
182
Michael Wright7b159c92015-05-14 14:48:03 +0100183static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700184 const PointerProperties* pointerProperties) {
185 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186 ALOGE("Motion event has invalid action code 0x%x", action);
187 return false;
188 }
189 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000190 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700191 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800192 return false;
193 }
194 BitSet32 pointerIdBits;
195 for (size_t i = 0; i < pointerCount; i++) {
196 int32_t id = pointerProperties[i].id;
197 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700198 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
199 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800200 return false;
201 }
202 if (pointerIdBits.hasBit(id)) {
203 ALOGE("Motion event has duplicate pointer id %d", id);
204 return false;
205 }
206 pointerIdBits.markBit(id);
207 }
208 return true;
209}
210
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000211static std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800212 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000213 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214 }
215
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000216 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217 bool first = true;
218 Region::const_iterator cur = region.begin();
219 Region::const_iterator const tail = region.end();
220 while (cur != tail) {
221 if (first) {
222 first = false;
223 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800224 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800225 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800226 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800227 cur++;
228 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000229 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800230}
231
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500232static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
233 constexpr size_t maxEntries = 50; // max events to print
234 constexpr size_t skipBegin = maxEntries / 2;
235 const size_t skipEnd = queue.size() - maxEntries / 2;
236 // skip from maxEntries / 2 ... size() - maxEntries/2
237 // only print from 0 .. skipBegin and then from skipEnd .. size()
238
239 std::string dump;
240 for (size_t i = 0; i < queue.size(); i++) {
241 const DispatchEntry& entry = *queue[i];
242 if (i >= skipBegin && i < skipEnd) {
243 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
244 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
245 continue;
246 }
247 dump.append(INDENT4);
248 dump += entry.eventEntry->getDescription();
249 dump += StringPrintf(", seq=%" PRIu32
250 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
251 entry.seq, entry.targetFlags, entry.resolvedAction,
252 ns2ms(currentTime - entry.eventEntry->eventTime));
253 if (entry.deliveryTime != 0) {
254 // This entry was delivered, so add information on how long we've been waiting
255 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
256 }
257 dump.append("\n");
258 }
259 return dump;
260}
261
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700262/**
263 * Find the entry in std::unordered_map by key, and return it.
264 * If the entry is not found, return a default constructed entry.
265 *
266 * Useful when the entries are vectors, since an empty vector will be returned
267 * if the entry is not found.
268 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
269 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700270template <typename K, typename V>
271static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700272 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700273 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800274}
275
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700276/**
277 * Find the entry in std::unordered_map by value, and remove it.
278 * If more than one entry has the same value, then all matching
279 * key-value pairs will be removed.
280 *
281 * Return true if at least one value has been removed.
282 */
283template <typename K, typename V>
284static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
285 bool removed = false;
286 for (auto it = map.begin(); it != map.end();) {
287 if (it->second == value) {
288 it = map.erase(it);
289 removed = true;
290 } else {
291 it++;
292 }
293 }
294 return removed;
295}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800296
Vishnu Nair958da932020-08-21 17:12:37 -0700297/**
298 * Find the entry in std::unordered_map by key and return the value as an optional.
299 */
300template <typename K, typename V>
301static std::optional<V> getOptionalValueByKey(const std::unordered_map<K, V>& map, K key) {
302 auto it = map.find(key);
303 return it != map.end() ? std::optional<V>{it->second} : std::nullopt;
304}
305
chaviwaf87b3e2019-10-01 16:59:28 -0700306static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
307 if (first == second) {
308 return true;
309 }
310
311 if (first == nullptr || second == nullptr) {
312 return false;
313 }
314
315 return first->getToken() == second->getToken();
316}
317
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800318static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
319 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
320}
321
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000322static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700323 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000324 int32_t inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700325 if (inputTarget.useDefaultPointerTransform()) {
326 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700327 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
chaviw1ff3d1e2020-07-01 15:53:47 -0700328 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000329 }
330
331 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
332 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
333
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700334 std::vector<PointerCoords> pointerCoords;
335 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000336
337 // Use the first pointer information to normalize all other pointers. This could be any pointer
338 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700339 // uses the transform for the normalized pointer.
340 const ui::Transform& firstPointerTransform =
341 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
342 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000343
344 // Iterate through all pointers in the event to normalize against the first.
345 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
346 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
347 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700348 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000349
350 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700351 // First, apply the current pointer's transform to update the coordinates into
352 // window space.
353 pointerCoords[pointerIndex].transform(currTransform);
354 // Next, apply the inverse transform of the normalized coordinates so the
355 // current coordinates are transformed into the normalized coordinate space.
356 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000357 }
358
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700359 std::unique_ptr<MotionEntry> combinedMotionEntry =
360 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
361 motionEntry.deviceId, motionEntry.source,
362 motionEntry.displayId, motionEntry.policyFlags,
363 motionEntry.action, motionEntry.actionButton,
364 motionEntry.flags, motionEntry.metaState,
365 motionEntry.buttonState, motionEntry.classification,
366 motionEntry.edgeFlags, motionEntry.xPrecision,
367 motionEntry.yPrecision, motionEntry.xCursorPosition,
368 motionEntry.yCursorPosition, motionEntry.downTime,
369 motionEntry.pointerCount, motionEntry.pointerProperties,
370 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000371
372 if (motionEntry.injectionState) {
373 combinedMotionEntry->injectionState = motionEntry.injectionState;
374 combinedMotionEntry->injectionState->refCount += 1;
375 }
376
377 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700378 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
379 firstPointerTransform, inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000380 return dispatchEntry;
381}
382
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700383static void addGestureMonitors(const std::vector<Monitor>& monitors,
384 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
385 float yOffset = 0) {
386 if (monitors.empty()) {
387 return;
388 }
389 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
390 for (const Monitor& monitor : monitors) {
391 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
392 }
393}
394
Garfield Tan15601662020-09-22 15:32:38 -0700395static status_t openInputChannelPair(const std::string& name,
396 std::shared_ptr<InputChannel>& serverChannel,
397 std::unique_ptr<InputChannel>& clientChannel) {
398 std::unique_ptr<InputChannel> uniqueServerChannel;
399 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
400
401 serverChannel = std::move(uniqueServerChannel);
402 return result;
403}
404
Vishnu Nair958da932020-08-21 17:12:37 -0700405const char* InputDispatcher::typeToString(InputDispatcher::FocusResult result) {
406 switch (result) {
407 case InputDispatcher::FocusResult::OK:
408 return "Ok";
409 case InputDispatcher::FocusResult::NO_WINDOW:
410 return "Window not found";
411 case InputDispatcher::FocusResult::NOT_FOCUSABLE:
412 return "Window not focusable";
413 case InputDispatcher::FocusResult::NOT_VISIBLE:
414 return "Window not visible";
415 }
416}
417
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500418template <typename T>
419static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
420 if (lhs == nullptr && rhs == nullptr) {
421 return true;
422 }
423 if (lhs == nullptr || rhs == nullptr) {
424 return false;
425 }
426 return *lhs == *rhs;
427}
428
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000429static sp<IPlatformCompatNative> getCompatService() {
430 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
431 if (service == nullptr) {
432 ALOGE("Failed to link to compat service");
433 return nullptr;
434 }
435 return interface_cast<IPlatformCompatNative>(service);
436}
437
Michael Wrightd02c5b62014-02-10 15:10:22 -0800438// --- InputDispatcher ---
439
Garfield Tan00f511d2019-06-12 16:55:40 -0700440InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
441 : mPolicy(policy),
442 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700443 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800444 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700445 mAppSwitchSawKeyDown(false),
446 mAppSwitchDueTime(LONG_LONG_MAX),
447 mNextUnblockedEvent(nullptr),
448 mDispatchEnabled(false),
449 mDispatchFrozen(false),
450 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800451 // mInTouchMode will be initialized by the WindowManager to the default device config.
452 // To avoid leaking stack in case that call never comes, and for tests,
453 // initialize it here anyways.
454 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100455 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000456 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
457 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800458 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800459 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800460
Yi Kong9b14ac62018-07-17 13:48:38 -0700461 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800462
463 policy->getDispatcherConfiguration(&mConfig);
464}
465
466InputDispatcher::~InputDispatcher() {
467 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800468 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800469
470 resetKeyRepeatLocked();
471 releasePendingEventLocked();
472 drainInboundQueueLocked();
473 }
474
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700475 while (!mConnectionsByFd.empty()) {
476 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700477 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800478 }
479}
480
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700481status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700482 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700483 return ALREADY_EXISTS;
484 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700485 mThread = std::make_unique<InputThread>(
486 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
487 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700488}
489
490status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700491 if (mThread && mThread->isCallingThread()) {
492 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700493 return INVALID_OPERATION;
494 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700495 mThread.reset();
496 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700497}
498
Michael Wrightd02c5b62014-02-10 15:10:22 -0800499void InputDispatcher::dispatchOnce() {
500 nsecs_t nextWakeupTime = LONG_LONG_MAX;
501 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800502 std::scoped_lock _l(mLock);
503 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800504
505 // Run a dispatch loop if there are no pending commands.
506 // The dispatch loop might enqueue commands to run afterwards.
507 if (!haveCommandsLocked()) {
508 dispatchOnceInnerLocked(&nextWakeupTime);
509 }
510
511 // Run all pending commands if there are any.
512 // If any commands were run then force the next poll to wake up immediately.
513 if (runCommandsLockedInterruptible()) {
514 nextWakeupTime = LONG_LONG_MIN;
515 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800516
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700517 // If we are still waiting for ack on some events,
518 // we might have to wake up earlier to check if an app is anr'ing.
519 const nsecs_t nextAnrCheck = processAnrsLocked();
520 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
521
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800522 // We are about to enter an infinitely long sleep, because we have no commands or
523 // pending or queued events
524 if (nextWakeupTime == LONG_LONG_MAX) {
525 mDispatcherEnteredIdle.notify_all();
526 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800527 } // release lock
528
529 // Wait for callback or timeout or wake. (make sure we round up, not down)
530 nsecs_t currentTime = now();
531 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
532 mLooper->pollOnce(timeoutMillis);
533}
534
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700535/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500536 * Raise ANR if there is no focused window.
537 * Before the ANR is raised, do a final state check:
538 * 1. The currently focused application must be the same one we are waiting for.
539 * 2. Ensure we still don't have a focused window.
540 */
541void InputDispatcher::processNoFocusedWindowAnrLocked() {
542 // Check if the application that we are waiting for is still focused.
543 std::shared_ptr<InputApplicationHandle> focusedApplication =
544 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
545 if (focusedApplication == nullptr ||
546 focusedApplication->getApplicationToken() !=
547 mAwaitedFocusedApplication->getApplicationToken()) {
548 // Unexpected because we should have reset the ANR timer when focused application changed
549 ALOGE("Waited for a focused window, but focused application has already changed to %s",
550 focusedApplication->getName().c_str());
551 return; // The focused application has changed.
552 }
553
554 const sp<InputWindowHandle>& focusedWindowHandle =
555 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
556 if (focusedWindowHandle != nullptr) {
557 return; // We now have a focused window. No need for ANR.
558 }
559 onAnrLocked(mAwaitedFocusedApplication);
560}
561
562/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700563 * Check if any of the connections' wait queues have events that are too old.
564 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
565 * Return the time at which we should wake up next.
566 */
567nsecs_t InputDispatcher::processAnrsLocked() {
568 const nsecs_t currentTime = now();
569 nsecs_t nextAnrCheck = LONG_LONG_MAX;
570 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
571 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
572 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500573 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700574 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500575 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700576 return LONG_LONG_MIN;
577 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500578 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700579 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
580 }
581 }
582
583 // Check if any connection ANRs are due
584 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
585 if (currentTime < nextAnrCheck) { // most likely scenario
586 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
587 }
588
589 // If we reached here, we have an unresponsive connection.
590 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
591 if (connection == nullptr) {
592 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
593 return nextAnrCheck;
594 }
595 connection->responsive = false;
596 // Stop waking up for this unresponsive connection
597 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -0500598 onAnrLocked(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700599 return LONG_LONG_MIN;
600}
601
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500602std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700603 sp<InputWindowHandle> window = getWindowHandleLocked(token);
604 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500605 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700606 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500607 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700608}
609
Michael Wrightd02c5b62014-02-10 15:10:22 -0800610void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
611 nsecs_t currentTime = now();
612
Jeff Browndc5992e2014-04-11 01:27:26 -0700613 // Reset the key repeat timer whenever normal dispatch is suspended while the
614 // device is in a non-interactive state. This is to ensure that we abort a key
615 // repeat if the device is just coming out of sleep.
616 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800617 resetKeyRepeatLocked();
618 }
619
620 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
621 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100622 if (DEBUG_FOCUS) {
623 ALOGD("Dispatch frozen. Waiting some more.");
624 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800625 return;
626 }
627
628 // Optimize latency of app switches.
629 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
630 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
631 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
632 if (mAppSwitchDueTime < *nextWakeupTime) {
633 *nextWakeupTime = mAppSwitchDueTime;
634 }
635
636 // Ready to start a new event.
637 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700638 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700639 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800640 if (isAppSwitchDue) {
641 // The inbound queue is empty so the app switch key we were waiting
642 // for will never arrive. Stop waiting for it.
643 resetPendingAppSwitchLocked(false);
644 isAppSwitchDue = false;
645 }
646
647 // Synthesize a key repeat if appropriate.
648 if (mKeyRepeatState.lastKeyEntry) {
649 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
650 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
651 } else {
652 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
653 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
654 }
655 }
656 }
657
658 // Nothing to do if there is no pending event.
659 if (!mPendingEvent) {
660 return;
661 }
662 } else {
663 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700664 mPendingEvent = mInboundQueue.front();
665 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800666 traceInboundQueueLengthLocked();
667 }
668
669 // Poke user activity for this event.
670 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700671 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800672 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800673 }
674
675 // Now we have an event to dispatch.
676 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700677 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800678 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700679 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800680 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700681 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800682 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700683 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800684 }
685
686 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700687 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800688 }
689
690 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700691 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700692 const ConfigurationChangedEntry& typedEntry =
693 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700694 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700695 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700696 break;
697 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800698
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700699 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700700 const DeviceResetEntry& typedEntry =
701 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700702 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700703 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700704 break;
705 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800706
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100707 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700708 std::shared_ptr<FocusEntry> typedEntry =
709 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100710 dispatchFocusLocked(currentTime, typedEntry);
711 done = true;
712 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
713 break;
714 }
715
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700716 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700717 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700718 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700719 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700720 resetPendingAppSwitchLocked(true);
721 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700722 } else if (dropReason == DropReason::NOT_DROPPED) {
723 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700724 }
725 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700726 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700727 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700728 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700729 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
730 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700731 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700732 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700733 break;
734 }
735
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700736 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700737 std::shared_ptr<MotionEntry> motionEntry =
738 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700739 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
740 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800741 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700742 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700743 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700744 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700745 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
746 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700747 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700748 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700749 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800750 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800751 }
752
753 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700754 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700755 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800756 }
Michael Wright3a981722015-06-10 15:26:13 +0100757 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800758
759 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700760 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800761 }
762}
763
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700764/**
765 * Return true if the events preceding this incoming motion event should be dropped
766 * Return false otherwise (the default behaviour)
767 */
768bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700769 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700770 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700771
772 // Optimize case where the current application is unresponsive and the user
773 // decides to touch a window in a different application.
774 // If the application takes too long to catch up then we drop all events preceding
775 // the touch into the other window.
776 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700777 int32_t displayId = motionEntry.displayId;
778 int32_t x = static_cast<int32_t>(
779 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
780 int32_t y = static_cast<int32_t>(
781 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
782 sp<InputWindowHandle> touchedWindowHandle =
783 findTouchedWindowAtLocked(displayId, x, y, nullptr);
784 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700785 touchedWindowHandle->getApplicationToken() !=
786 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700787 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700788 ALOGI("Pruning input queue because user touched a different application while waiting "
789 "for %s",
790 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700791 return true;
792 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700793
794 // Alternatively, maybe there's a gesture monitor that could handle this event
795 std::vector<TouchedMonitor> gestureMonitors =
796 findTouchedGestureMonitorsLocked(displayId, {});
797 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
798 sp<Connection> connection =
799 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000800 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700801 // This monitor could take more input. Drop all events preceding this
802 // event, so that gesture monitor could get a chance to receive the stream
803 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
804 "responsive gesture monitor that may handle the event",
805 mAwaitedFocusedApplication->getName().c_str());
806 return true;
807 }
808 }
809 }
810
811 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
812 // yet been processed by some connections, the dispatcher will wait for these motion
813 // events to be processed before dispatching the key event. This is because these motion events
814 // may cause a new window to be launched, which the user might expect to receive focus.
815 // To prevent waiting forever for such events, just send the key to the currently focused window
816 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
817 ALOGD("Received a new pointer down event, stop waiting for events to process and "
818 "just send the pending key event to the focused window.");
819 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700820 }
821 return false;
822}
823
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700824bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700825 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700826 mInboundQueue.push_back(std::move(newEntry));
827 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800828 traceInboundQueueLengthLocked();
829
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700830 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700831 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700832 // Optimize app switch latency.
833 // If the application takes too long to catch up then we drop all events preceding
834 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700835 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700836 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700837 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700838 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700839 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700840 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800841#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700842 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800843#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700844 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700845 mAppSwitchSawKeyDown = false;
846 needWake = true;
847 }
848 }
849 }
850 break;
851 }
852
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700853 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700854 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
855 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700856 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800857 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700858 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800859 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100860 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700861 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
862 break;
863 }
864 case EventEntry::Type::CONFIGURATION_CHANGED:
865 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700866 // nothing to do
867 break;
868 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800869 }
870
871 return needWake;
872}
873
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700874void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700875 mRecentQueue.push_back(entry);
876 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700877 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800878 }
879}
880
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700881sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700882 int32_t y, TouchState* touchState,
883 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700884 bool addPortalWindows) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700885 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
886 LOG_ALWAYS_FATAL(
887 "Must provide a valid touch state if adding portal windows or outside targets");
888 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800889 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700890 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800891 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800892 const InputWindowInfo* windowInfo = windowHandle->getInfo();
893 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100894 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800895
896 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100897 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
898 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
899 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800900 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800901 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700902 if (portalToDisplayId != ADISPLAY_ID_NONE &&
903 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800904 if (addPortalWindows) {
905 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700906 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800907 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700908 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700909 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800910 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800911 // Found window.
912 return windowHandle;
913 }
914 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800915
Michael Wright44753b12020-07-08 13:48:11 +0100916 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700917 touchState->addOrUpdateWindow(windowHandle,
918 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
919 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800920 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800921 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800922 }
923 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700924 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800925}
926
Garfield Tane84e6f92019-08-29 17:28:41 -0700927std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700928 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000929 std::vector<TouchedMonitor> touchedMonitors;
930
931 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
932 addGestureMonitors(monitors, touchedMonitors);
933 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
934 const InputWindowInfo* windowInfo = portalWindow->getInfo();
935 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700936 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
937 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000938 }
939 return touchedMonitors;
940}
941
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700942void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800943 const char* reason;
944 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700945 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800946#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700947 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800948#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700949 reason = "inbound event was dropped because the policy consumed it";
950 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700951 case DropReason::DISABLED:
952 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700953 ALOGI("Dropped event because input dispatch is disabled.");
954 }
955 reason = "inbound event was dropped because input dispatch is disabled";
956 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700957 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700958 ALOGI("Dropped event because of pending overdue app switch.");
959 reason = "inbound event was dropped because of pending overdue app switch";
960 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700961 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700962 ALOGI("Dropped event because the current application is not responding and the user "
963 "has started interacting with a different application.");
964 reason = "inbound event was dropped because the current application is not responding "
965 "and the user has started interacting with a different application";
966 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700967 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700968 ALOGI("Dropped event because it is stale.");
969 reason = "inbound event was dropped because it is stale";
970 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700971 case DropReason::NOT_DROPPED: {
972 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700973 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700974 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800975 }
976
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700977 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700978 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800979 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
980 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700981 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800982 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700983 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700984 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
985 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700986 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
987 synthesizeCancelationEventsForAllConnectionsLocked(options);
988 } else {
989 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
990 synthesizeCancelationEventsForAllConnectionsLocked(options);
991 }
992 break;
993 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100994 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700995 case EventEntry::Type::CONFIGURATION_CHANGED:
996 case EventEntry::Type::DEVICE_RESET: {
997 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
998 break;
999 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001000 }
1001}
1002
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001003static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001004 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1005 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001006}
1007
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001008bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1009 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1010 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1011 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001012}
1013
1014bool InputDispatcher::isAppSwitchPendingLocked() {
1015 return mAppSwitchDueTime != LONG_LONG_MAX;
1016}
1017
1018void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1019 mAppSwitchDueTime = LONG_LONG_MAX;
1020
1021#if DEBUG_APP_SWITCH
1022 if (handled) {
1023 ALOGD("App switch has arrived.");
1024 } else {
1025 ALOGD("App switch was abandoned.");
1026 }
1027#endif
1028}
1029
Michael Wrightd02c5b62014-02-10 15:10:22 -08001030bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001031 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001032}
1033
1034bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001035 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001036 return false;
1037 }
1038
1039 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001040 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001041 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001042 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001043 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001044
1045 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001046 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001047 return true;
1048}
1049
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001050void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1051 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001052}
1053
1054void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001055 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001056 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001057 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001058 releaseInboundEventLocked(entry);
1059 }
1060 traceInboundQueueLengthLocked();
1061}
1062
1063void InputDispatcher::releasePendingEventLocked() {
1064 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001065 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001066 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001067 }
1068}
1069
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001070void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001071 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001072 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001073#if DEBUG_DISPATCH_CYCLE
1074 ALOGD("Injected inbound event was dropped.");
1075#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001076 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001077 }
1078 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001079 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080 }
1081 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001082}
1083
1084void InputDispatcher::resetKeyRepeatLocked() {
1085 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001086 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001087 }
1088}
1089
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001090std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1091 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001092
Michael Wright2e732952014-09-24 13:26:59 -07001093 uint32_t policyFlags = entry->policyFlags &
1094 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001095
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001096 std::shared_ptr<KeyEntry> newEntry =
1097 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1098 entry->source, entry->displayId, policyFlags, entry->action,
1099 entry->flags, entry->keyCode, entry->scanCode,
1100 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001101
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001102 newEntry->syntheticRepeat = true;
1103 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001104 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001105 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001106}
1107
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001108bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001109 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001110#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001111 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001112#endif
1113
1114 // Reset key repeating in case a keyboard device was added or removed or something.
1115 resetKeyRepeatLocked();
1116
1117 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001118 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1119 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001120 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001121 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001122 return true;
1123}
1124
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001125bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1126 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001127#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001128 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1129 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130#endif
1131
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001132 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001133 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001134 synthesizeCancelationEventsForAllConnectionsLocked(options);
1135 return true;
1136}
1137
Vishnu Nairad321cd2020-08-20 16:40:21 -07001138void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001139 std::string_view reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001140 if (mPendingEvent != nullptr) {
1141 // Move the pending event to the front of the queue. This will give the chance
1142 // for the pending event to get dispatched to the newly focused window
1143 mInboundQueue.push_front(mPendingEvent);
1144 mPendingEvent = nullptr;
1145 }
1146
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001147 std::unique_ptr<FocusEntry> focusEntry =
1148 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1149 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001150
1151 // This event should go to the front of the queue, but behind all other focus events
1152 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001153 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001154 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001155 [](const std::shared_ptr<EventEntry>& event) {
1156 return event->type == EventEntry::Type::FOCUS;
1157 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001158
1159 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001160 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001161}
1162
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001163void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001164 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001165 if (channel == nullptr) {
1166 return; // Window has gone away
1167 }
1168 InputTarget target;
1169 target.inputChannel = channel;
1170 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1171 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001172 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1173 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001174 std::string reason = std::string("reason=").append(entry->reason);
1175 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001176 dispatchEventLocked(currentTime, entry, {target});
1177}
1178
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001179bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001180 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001181 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001182 if (!entry->dispatchInProgress) {
1183 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1184 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1185 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1186 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001187 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001188 // We have seen two identical key downs in a row which indicates that the device
1189 // driver is automatically generating key repeats itself. We take note of the
1190 // repeat here, but we disable our own next key repeat timer since it is clear that
1191 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001192 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1193 // Make sure we don't get key down from a different device. If a different
1194 // device Id has same key pressed down, the new device Id will replace the
1195 // current one to hold the key repeat with repeat count reset.
1196 // In the future when got a KEY_UP on the device id, drop it and do not
1197 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001198 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1199 resetKeyRepeatLocked();
1200 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1201 } else {
1202 // Not a repeat. Save key down state in case we do see a repeat later.
1203 resetKeyRepeatLocked();
1204 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1205 }
1206 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001207 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1208 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001209 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001210#if DEBUG_INBOUND_EVENT_DETAILS
1211 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1212#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001213 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001214 resetKeyRepeatLocked();
1215 }
1216
1217 if (entry->repeatCount == 1) {
1218 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1219 } else {
1220 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1221 }
1222
1223 entry->dispatchInProgress = true;
1224
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001225 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001226 }
1227
1228 // Handle case where the policy asked us to try again later last time.
1229 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1230 if (currentTime < entry->interceptKeyWakeupTime) {
1231 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1232 *nextWakeupTime = entry->interceptKeyWakeupTime;
1233 }
1234 return false; // wait until next wakeup
1235 }
1236 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1237 entry->interceptKeyWakeupTime = 0;
1238 }
1239
1240 // Give the policy a chance to intercept the key.
1241 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1242 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001243 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001244 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001245 sp<IBinder> focusedWindowToken =
1246 getValueByKey(mFocusedWindowTokenByDisplay, getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001247 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001248 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001249 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001250 return false; // wait for the command to run
1251 } else {
1252 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1253 }
1254 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001255 if (*dropReason == DropReason::NOT_DROPPED) {
1256 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001257 }
1258 }
1259
1260 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001261 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001262 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001263 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1264 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001265 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001266 return true;
1267 }
1268
1269 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001270 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001271 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001272 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001273 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001274 return false;
1275 }
1276
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001277 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001278 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001279 return true;
1280 }
1281
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001282 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001283 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001284
1285 // Dispatch the key.
1286 dispatchEventLocked(currentTime, entry, inputTargets);
1287 return true;
1288}
1289
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001290void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001291#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001292 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001293 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1294 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001295 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1296 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1297 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001298#endif
1299}
1300
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001301bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001302 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001303 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001304 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001305 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001306 entry->dispatchInProgress = true;
1307
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001308 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001309 }
1310
1311 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001312 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001313 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001314 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1315 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001316 return true;
1317 }
1318
1319 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1320
1321 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001322 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001323
1324 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001325 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001326 if (isPointerEvent) {
1327 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001328 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001329 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001330 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001331 } else {
1332 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001333 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001334 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001335 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001336 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001337 return false;
1338 }
1339
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001340 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001341 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001342 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1343 return true;
1344 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001345 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001346 CancelationOptions::Mode mode(isPointerEvent
1347 ? CancelationOptions::CANCEL_POINTER_EVENTS
1348 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1349 CancelationOptions options(mode, "input event injection failed");
1350 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001351 return true;
1352 }
1353
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001354 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001355 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001356
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001357 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001358 std::unordered_map<int32_t, TouchState>::iterator it =
1359 mTouchStatesByDisplay.find(entry->displayId);
1360 if (it != mTouchStatesByDisplay.end()) {
1361 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001362 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001363 // The event has gone through these portal windows, so we add monitoring targets of
1364 // the corresponding displays as well.
1365 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001366 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001367 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001368 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001369 }
1370 }
1371 }
1372 }
1373
Michael Wrightd02c5b62014-02-10 15:10:22 -08001374 // Dispatch the motion.
1375 if (conflictingPointerActions) {
1376 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001377 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001378 synthesizeCancelationEventsForAllConnectionsLocked(options);
1379 }
1380 dispatchEventLocked(currentTime, entry, inputTargets);
1381 return true;
1382}
1383
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001384void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001385#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001386 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001387 ", policyFlags=0x%x, "
1388 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1389 "metaState=0x%x, buttonState=0x%x,"
1390 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001391 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1392 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1393 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001394
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001395 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001396 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001397 "x=%f, y=%f, pressure=%f, size=%f, "
1398 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1399 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001400 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1401 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1402 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1403 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1404 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1405 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1406 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1407 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1408 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1409 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001410 }
1411#endif
1412}
1413
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001414void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1415 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001416 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001417 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001418#if DEBUG_DISPATCH_CYCLE
1419 ALOGD("dispatchEventToCurrentInputTargets");
1420#endif
1421
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001422 updateInteractionTokensLocked(*eventEntry, inputTargets);
1423
Michael Wrightd02c5b62014-02-10 15:10:22 -08001424 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1425
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001426 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001427
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001428 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001429 sp<Connection> connection =
1430 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001431 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001432 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001433 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001434 if (DEBUG_FOCUS) {
1435 ALOGD("Dropping event delivery to target with channel '%s' because it "
1436 "is no longer registered with the input dispatcher.",
1437 inputTarget.inputChannel->getName().c_str());
1438 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001439 }
1440 }
1441}
1442
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001443void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1444 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1445 // If the policy decides to close the app, we will get a channel removal event via
1446 // unregisterInputChannel, and will clean up the connection that way. We are already not
1447 // sending new pointers to the connection when it blocked, but focused events will continue to
1448 // pile up.
1449 ALOGW("Canceling events for %s because it is unresponsive",
1450 connection->inputChannel->getName().c_str());
1451 if (connection->status == Connection::STATUS_NORMAL) {
1452 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1453 "application not responding");
1454 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001455 }
1456}
1457
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001458void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001459 if (DEBUG_FOCUS) {
1460 ALOGD("Resetting ANR timeouts.");
1461 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001462
1463 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001464 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001465 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001466}
1467
Tiger Huang721e26f2018-07-24 22:26:19 +08001468/**
1469 * Get the display id that the given event should go to. If this event specifies a valid display id,
1470 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1471 * Focused display is the display that the user most recently interacted with.
1472 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001473int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001474 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001475 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001476 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001477 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1478 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001479 break;
1480 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001481 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001482 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1483 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001484 break;
1485 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001486 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001487 case EventEntry::Type::CONFIGURATION_CHANGED:
1488 case EventEntry::Type::DEVICE_RESET: {
1489 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001490 return ADISPLAY_ID_NONE;
1491 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001492 }
1493 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1494}
1495
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001496bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1497 const char* focusedWindowName) {
1498 if (mAnrTracker.empty()) {
1499 // already processed all events that we waited for
1500 mKeyIsWaitingForEventsTimeout = std::nullopt;
1501 return false;
1502 }
1503
1504 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1505 // Start the timer
1506 ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
1507 "focus to change",
1508 focusedWindowName);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001509 mKeyIsWaitingForEventsTimeout = currentTime +
1510 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1511 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001512 return true;
1513 }
1514
1515 // We still have pending events, and already started the timer
1516 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1517 return true; // Still waiting
1518 }
1519
1520 // Waited too long, and some connection still hasn't processed all motions
1521 // Just send the key to the focused window
1522 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1523 focusedWindowName);
1524 mKeyIsWaitingForEventsTimeout = std::nullopt;
1525 return false;
1526}
1527
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001528InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1529 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1530 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001531 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001532
Tiger Huang721e26f2018-07-24 22:26:19 +08001533 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001534 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001535 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001536 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1537
Michael Wrightd02c5b62014-02-10 15:10:22 -08001538 // If there is no currently focused window and no focused application
1539 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001540 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1541 ALOGI("Dropping %s event because there is no focused window or focused application in "
1542 "display %" PRId32 ".",
1543 EventEntry::typeToString(entry.type), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001544 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001545 }
1546
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001547 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1548 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1549 // start interacting with another application via touch (app switch). This code can be removed
1550 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1551 // an app is expected to have a focused window.
1552 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1553 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1554 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001555 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1556 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1557 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001558 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001559 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001560 ALOGW("Waiting because no window has focus but %s may eventually add a "
1561 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001562 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001563 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001564 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001565 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1566 // Already raised ANR. Drop the event
1567 ALOGE("Dropping %s event because there is no focused window",
1568 EventEntry::typeToString(entry.type));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001569 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001570 } else {
1571 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001572 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001573 }
1574 }
1575
1576 // we have a valid, non-null focused window
1577 resetNoFocusedWindowTimeoutLocked();
1578
Michael Wrightd02c5b62014-02-10 15:10:22 -08001579 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001580 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001581 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001582 }
1583
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001584 if (focusedWindowHandle->getInfo()->paused) {
1585 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001586 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001587 }
1588
1589 // If the event is a key event, then we must wait for all previous events to
1590 // complete before delivering it because previous events may have the
1591 // side-effect of transferring focus to a different window and we want to
1592 // ensure that the following keys are sent to the new window.
1593 //
1594 // Suppose the user touches a button in a window then immediately presses "A".
1595 // If the button causes a pop-up window to appear then we want to ensure that
1596 // the "A" key is delivered to the new pop-up window. This is because users
1597 // often anticipate pending UI changes when typing on a keyboard.
1598 // To obtain this behavior, we must serialize key events with respect to all
1599 // prior input events.
1600 if (entry.type == EventEntry::Type::KEY) {
1601 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1602 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001603 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001604 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605 }
1606
1607 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001608 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001609 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1610 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001611
1612 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001613 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001614}
1615
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001616/**
1617 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1618 * that are currently unresponsive.
1619 */
1620std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1621 const std::vector<TouchedMonitor>& monitors) const {
1622 std::vector<TouchedMonitor> responsiveMonitors;
1623 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1624 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1625 sp<Connection> connection = getConnectionLocked(
1626 monitor.monitor.inputChannel->getConnectionToken());
1627 if (connection == nullptr) {
1628 ALOGE("Could not find connection for monitor %s",
1629 monitor.monitor.inputChannel->getName().c_str());
1630 return false;
1631 }
1632 if (!connection->responsive) {
1633 ALOGW("Unresponsive monitor %s will not get the new gesture",
1634 connection->inputChannel->getName().c_str());
1635 return false;
1636 }
1637 return true;
1638 });
1639 return responsiveMonitors;
1640}
1641
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001642InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1643 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1644 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001645 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001646 enum InjectionPermission {
1647 INJECTION_PERMISSION_UNKNOWN,
1648 INJECTION_PERMISSION_GRANTED,
1649 INJECTION_PERMISSION_DENIED
1650 };
1651
Michael Wrightd02c5b62014-02-10 15:10:22 -08001652 // For security reasons, we defer updating the touch state until we are sure that
1653 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001654 int32_t displayId = entry.displayId;
1655 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001656 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1657
1658 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001659 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001660 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001661 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1662 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001663
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001664 // Copy current touch state into tempTouchState.
1665 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1666 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001667 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001668 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001669 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1670 mTouchStatesByDisplay.find(displayId);
1671 if (oldStateIt != mTouchStatesByDisplay.end()) {
1672 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001673 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001674 }
1675
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001676 bool isSplit = tempTouchState.split;
1677 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1678 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1679 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001680 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1681 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1682 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1683 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1684 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001685 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001686 bool wrongDevice = false;
1687 if (newGesture) {
1688 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001689 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001690 ALOGI("Dropping event because a pointer for a different device is already down "
1691 "in display %" PRId32,
1692 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001693 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001694 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001695 switchedDevice = false;
1696 wrongDevice = true;
1697 goto Failed;
1698 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001699 tempTouchState.reset();
1700 tempTouchState.down = down;
1701 tempTouchState.deviceId = entry.deviceId;
1702 tempTouchState.source = entry.source;
1703 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001704 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001705 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001706 ALOGI("Dropping move event because a pointer for a different device is already active "
1707 "in display %" PRId32,
1708 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001709 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001710 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001711 switchedDevice = false;
1712 wrongDevice = true;
1713 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001714 }
1715
1716 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1717 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1718
Garfield Tan00f511d2019-06-12 16:55:40 -07001719 int32_t x;
1720 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001721 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001722 // Always dispatch mouse events to cursor position.
1723 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001724 x = int32_t(entry.xCursorPosition);
1725 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001726 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001727 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1728 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001729 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001730 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001731 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001732 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1733 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001734
1735 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001736 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001737 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001738
Michael Wrightd02c5b62014-02-10 15:10:22 -08001739 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001740 if (newTouchedWindowHandle != nullptr &&
1741 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001742 // New window supports splitting, but we should never split mouse events.
1743 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001744 } else if (isSplit) {
1745 // New window does not support splitting but we have already split events.
1746 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001747 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001748 }
1749
1750 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001751 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001752 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001753 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001754 }
1755
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001756 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1757 ALOGI("Not sending touch event to %s because it is paused",
1758 newTouchedWindowHandle->getName().c_str());
1759 newTouchedWindowHandle = nullptr;
1760 }
1761
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001762 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001763 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001764 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1765 if (!isResponsive) {
1766 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001767 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1768 newTouchedWindowHandle = nullptr;
1769 }
1770 }
1771
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001772 // Drop events that can't be trusted due to occlusion
1773 if (newTouchedWindowHandle != nullptr &&
1774 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1775 TouchOcclusionInfo occlusionInfo =
1776 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001777 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001778 if (DEBUG_TOUCH_OCCLUSION) {
1779 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1780 for (const auto& log : occlusionInfo.debugInfo) {
1781 ALOGD("%s", log.c_str());
1782 }
1783 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001784 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
1785 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1786 ALOGW("Dropping untrusted touch event due to %s/%d",
1787 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1788 newTouchedWindowHandle = nullptr;
1789 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001790 }
1791 }
1792
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001793 // Also don't send the new touch event to unresponsive gesture monitors
1794 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1795
Michael Wright3dd60e22019-03-27 22:06:44 +00001796 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1797 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001798 "(%d, %d) in display %" PRId32 ".",
1799 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001800 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001801 goto Failed;
1802 }
1803
1804 if (newTouchedWindowHandle != nullptr) {
1805 // Set target flags.
1806 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1807 if (isSplit) {
1808 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001809 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001810 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1811 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1812 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1813 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1814 }
1815
1816 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07001817 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
1818 newHoverWindowHandle = nullptr;
1819 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001820 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00001821 }
1822
1823 // Update the temporary touch state.
1824 BitSet32 pointerIds;
1825 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001826 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001827 pointerIds.markBit(pointerId);
1828 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001829 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001830 }
1831
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001832 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001833 } else {
1834 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1835
1836 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001837 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001838 if (DEBUG_FOCUS) {
1839 ALOGD("Dropping event because the pointer is not down or we previously "
1840 "dropped the pointer down event in display %" PRId32,
1841 displayId);
1842 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001843 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001844 goto Failed;
1845 }
1846
1847 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001848 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001849 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001850 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1851 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001852
1853 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001854 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07001855 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001856 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1857 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001858 if (DEBUG_FOCUS) {
1859 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1860 oldTouchedWindowHandle->getName().c_str(),
1861 newTouchedWindowHandle->getName().c_str(), displayId);
1862 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001863 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001864 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1865 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1866 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001867
1868 // Make a slippery entrance into the new window.
1869 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1870 isSplit = true;
1871 }
1872
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001873 int32_t targetFlags =
1874 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001875 if (isSplit) {
1876 targetFlags |= InputTarget::FLAG_SPLIT;
1877 }
1878 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1879 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10001880 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1881 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001882 }
1883
1884 BitSet32 pointerIds;
1885 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001886 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001887 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001888 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001889 }
1890 }
1891 }
1892
1893 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07001894 // Let the previous window know that the hover sequence is over, unless we already did it
1895 // when dispatching it as is to newTouchedWindowHandle.
1896 if (mLastHoverWindowHandle != nullptr &&
1897 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
1898 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001899#if DEBUG_HOVER
1900 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001901 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001902#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001903 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1904 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001905 }
1906
Garfield Tandf26e862020-07-01 20:18:19 -07001907 // Let the new window know that the hover sequence is starting, unless we already did it
1908 // when dispatching it as is to newTouchedWindowHandle.
1909 if (newHoverWindowHandle != nullptr &&
1910 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
1911 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001912#if DEBUG_HOVER
1913 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001914 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001915#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001916 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1917 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1918 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001919 }
1920 }
1921
1922 // Check permission to inject into all touched foreground windows and ensure there
1923 // is at least one touched foreground window.
1924 {
1925 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001926 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001927 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1928 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001929 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001930 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001931 injectionPermission = INJECTION_PERMISSION_DENIED;
1932 goto Failed;
1933 }
1934 }
1935 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001936 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00001937 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001938 ALOGI("Dropping event because there is no touched foreground window in display "
1939 "%" PRId32 " or gesture monitor to receive it.",
1940 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001941 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001942 goto Failed;
1943 }
1944
1945 // Permission granted to injection into all touched foreground windows.
1946 injectionPermission = INJECTION_PERMISSION_GRANTED;
1947 }
1948
1949 // Check whether windows listening for outside touches are owned by the same UID. If it is
1950 // set the policy flag that we will not reveal coordinate information to this window.
1951 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1952 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001953 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001954 if (foregroundWindowHandle) {
1955 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001956 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001957 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1958 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1959 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001960 tempTouchState.addOrUpdateWindow(inputWindowHandle,
1961 InputTarget::FLAG_ZERO_COORDS,
1962 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001963 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001964 }
1965 }
1966 }
1967 }
1968
Michael Wrightd02c5b62014-02-10 15:10:22 -08001969 // If this is the first pointer going down and the touched window has a wallpaper
1970 // then also add the touched wallpaper windows so they are locked in for the duration
1971 // of the touch gesture.
1972 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1973 // engine only supports touch events. We would need to add a mechanism similar
1974 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1975 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1976 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001977 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001978 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001979 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001980 getWindowHandlesLocked(displayId);
1981 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001982 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001983 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01001984 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001985 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001986 .addOrUpdateWindow(windowHandle,
1987 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1988 InputTarget::
1989 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1990 InputTarget::FLAG_DISPATCH_AS_IS,
1991 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001992 }
1993 }
1994 }
1995 }
1996
1997 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001998 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001999
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002000 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002001 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002002 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002003 }
2004
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002005 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002006 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002007 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002008 }
2009
Michael Wrightd02c5b62014-02-10 15:10:22 -08002010 // Drop the outside or hover touch windows since we will not care about them
2011 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002012 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002013
2014Failed:
2015 // Check injection permission once and for all.
2016 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002017 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002018 injectionPermission = INJECTION_PERMISSION_GRANTED;
2019 } else {
2020 injectionPermission = INJECTION_PERMISSION_DENIED;
2021 }
2022 }
2023
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002024 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2025 return injectionResult;
2026 }
2027
Michael Wrightd02c5b62014-02-10 15:10:22 -08002028 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002029 if (!wrongDevice) {
2030 if (switchedDevice) {
2031 if (DEBUG_FOCUS) {
2032 ALOGD("Conflicting pointer actions: Switched to a different device.");
2033 }
2034 *outConflictingPointerActions = true;
2035 }
2036
2037 if (isHoverAction) {
2038 // Started hovering, therefore no longer down.
2039 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002040 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002041 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2042 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002043 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002044 *outConflictingPointerActions = true;
2045 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002046 tempTouchState.reset();
2047 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2048 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2049 tempTouchState.deviceId = entry.deviceId;
2050 tempTouchState.source = entry.source;
2051 tempTouchState.displayId = displayId;
2052 }
2053 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2054 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2055 // All pointers up or canceled.
2056 tempTouchState.reset();
2057 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2058 // First pointer went down.
2059 if (oldState && oldState->down) {
2060 if (DEBUG_FOCUS) {
2061 ALOGD("Conflicting pointer actions: Down received while already down.");
2062 }
2063 *outConflictingPointerActions = true;
2064 }
2065 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2066 // One pointer went up.
2067 if (isSplit) {
2068 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2069 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002070
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002071 for (size_t i = 0; i < tempTouchState.windows.size();) {
2072 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2073 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2074 touchedWindow.pointerIds.clearBit(pointerId);
2075 if (touchedWindow.pointerIds.isEmpty()) {
2076 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2077 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002078 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002079 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002080 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002081 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002082 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002083 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002084
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002085 // Save changes unless the action was scroll in which case the temporary touch
2086 // state was only valid for this one action.
2087 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2088 if (tempTouchState.displayId >= 0) {
2089 mTouchStatesByDisplay[displayId] = tempTouchState;
2090 } else {
2091 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002092 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002093 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002094
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002095 // Update hover state.
2096 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002097 }
2098
Michael Wrightd02c5b62014-02-10 15:10:22 -08002099 return injectionResult;
2100}
2101
2102void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002103 int32_t targetFlags, BitSet32 pointerIds,
2104 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002105 std::vector<InputTarget>::iterator it =
2106 std::find_if(inputTargets.begin(), inputTargets.end(),
2107 [&windowHandle](const InputTarget& inputTarget) {
2108 return inputTarget.inputChannel->getConnectionToken() ==
2109 windowHandle->getToken();
2110 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002111
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002112 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002113
2114 if (it == inputTargets.end()) {
2115 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002116 std::shared_ptr<InputChannel> inputChannel =
2117 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002118 if (inputChannel == nullptr) {
2119 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2120 return;
2121 }
2122 inputTarget.inputChannel = inputChannel;
2123 inputTarget.flags = targetFlags;
2124 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2125 inputTargets.push_back(inputTarget);
2126 it = inputTargets.end() - 1;
2127 }
2128
2129 ALOG_ASSERT(it->flags == targetFlags);
2130 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2131
chaviw1ff3d1e2020-07-01 15:53:47 -07002132 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002133}
2134
Michael Wright3dd60e22019-03-27 22:06:44 +00002135void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002136 int32_t displayId, float xOffset,
2137 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002138 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2139 mGlobalMonitorsByDisplay.find(displayId);
2140
2141 if (it != mGlobalMonitorsByDisplay.end()) {
2142 const std::vector<Monitor>& monitors = it->second;
2143 for (const Monitor& monitor : monitors) {
2144 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002145 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002146 }
2147}
2148
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002149void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2150 float yOffset,
2151 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002152 InputTarget target;
2153 target.inputChannel = monitor.inputChannel;
2154 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002155 ui::Transform t;
2156 t.set(xOffset, yOffset);
2157 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002158 inputTargets.push_back(target);
2159}
2160
Michael Wrightd02c5b62014-02-10 15:10:22 -08002161bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002162 const InjectionState* injectionState) {
2163 if (injectionState &&
2164 (windowHandle == nullptr ||
2165 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2166 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002167 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002168 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002169 "owned by uid %d",
2170 injectionState->injectorPid, injectionState->injectorUid,
2171 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002172 } else {
2173 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002174 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002175 }
2176 return false;
2177 }
2178 return true;
2179}
2180
Robert Carrc9bf1d32020-04-13 17:21:08 -07002181/**
2182 * Indicate whether one window handle should be considered as obscuring
2183 * another window handle. We only check a few preconditions. Actually
2184 * checking the bounds is left to the caller.
2185 */
2186static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2187 const sp<InputWindowHandle>& otherHandle) {
2188 // Compare by token so cloned layers aren't counted
2189 if (haveSameToken(windowHandle, otherHandle)) {
2190 return false;
2191 }
2192 auto info = windowHandle->getInfo();
2193 auto otherInfo = otherHandle->getInfo();
2194 if (!otherInfo->visible) {
2195 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002196 } else if (otherInfo->alpha == 0 &&
2197 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2198 // Those act as if they were invisible, so we don't need to flag them.
2199 // We do want to potentially flag touchable windows even if they have 0
2200 // opacity, since they can consume touches and alter the effects of the
2201 // user interaction (eg. apps that rely on
2202 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2203 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2204 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002205 } else if (info->ownerUid == otherInfo->ownerUid) {
2206 // If ownerUid is the same we don't generate occlusion events as there
2207 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002208 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002209 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002210 return false;
2211 } else if (otherInfo->displayId != info->displayId) {
2212 return false;
2213 }
2214 return true;
2215}
2216
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002217/**
2218 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2219 * untrusted, one should check:
2220 *
2221 * 1. If result.hasBlockingOcclusion is true.
2222 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2223 * BLOCK_UNTRUSTED.
2224 *
2225 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2226 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2227 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2228 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2229 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2230 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2231 *
2232 * If neither of those is true, then it means the touch can be allowed.
2233 */
2234InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2235 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002236 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2237 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002238 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2239 TouchOcclusionInfo info;
2240 info.hasBlockingOcclusion = false;
2241 info.obscuringOpacity = 0;
2242 info.obscuringUid = -1;
2243 std::map<int32_t, float> opacityByUid;
2244 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2245 if (windowHandle == otherHandle) {
2246 break; // All future windows are below us. Exit early.
2247 }
2248 const InputWindowInfo* otherInfo = otherHandle->getInfo();
2249 if (canBeObscuredBy(windowHandle, otherHandle) &&
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002250 windowInfo->ownerUid != otherInfo->ownerUid && otherInfo->frameContainsPoint(x, y)) {
2251 if (DEBUG_TOUCH_OCCLUSION) {
2252 info.debugInfo.push_back(
2253 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2254 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002255 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2256 // we perform the checks below to see if the touch can be propagated or not based on the
2257 // window's touch occlusion mode
2258 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2259 info.hasBlockingOcclusion = true;
2260 info.obscuringUid = otherInfo->ownerUid;
2261 info.obscuringPackage = otherInfo->packageName;
2262 break;
2263 }
2264 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2265 uint32_t uid = otherInfo->ownerUid;
2266 float opacity =
2267 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2268 // Given windows A and B:
2269 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2270 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2271 opacityByUid[uid] = opacity;
2272 if (opacity > info.obscuringOpacity) {
2273 info.obscuringOpacity = opacity;
2274 info.obscuringUid = uid;
2275 info.obscuringPackage = otherInfo->packageName;
2276 }
2277 }
2278 }
2279 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002280 if (DEBUG_TOUCH_OCCLUSION) {
2281 info.debugInfo.push_back(
2282 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2283 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002284 return info;
2285}
2286
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002287std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2288 bool isTouchedWindow) const {
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002289 return StringPrintf(INDENT2 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32
2290 ", mode=%s, alpha=%.2f, "
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002291 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2292 "], touchableRegion=%s, window={%s}, applicationInfo=%s, "
2293 "flags={%s}, inputFeatures={%s}, hasToken=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002294 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002295 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002296 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002297 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2298 info->frameTop, info->frameRight, info->frameBottom,
2299 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002300 info->applicationInfo.name.c_str(), info->flags.string().c_str(),
2301 info->inputFeatures.string().c_str(), toString(info->token != nullptr));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002302}
2303
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002304bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2305 if (occlusionInfo.hasBlockingOcclusion) {
2306 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2307 occlusionInfo.obscuringUid);
2308 return false;
2309 }
2310 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2311 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2312 "%.2f, maximum allowed = %.2f)",
2313 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2314 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2315 return false;
2316 }
2317 return true;
2318}
2319
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002320bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2321 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002322 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002323 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002324 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002325 if (windowHandle == otherHandle) {
2326 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002327 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002328 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002329 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002330 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002331 return true;
2332 }
2333 }
2334 return false;
2335}
2336
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002337bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2338 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002339 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002340 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002341 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002342 if (windowHandle == otherHandle) {
2343 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002344 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002345 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002346 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002347 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002348 return true;
2349 }
2350 }
2351 return false;
2352}
2353
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002354std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002355 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002356 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002357 if (applicationHandle != nullptr) {
2358 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002359 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002360 } else {
2361 return applicationHandle->getName();
2362 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002363 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002364 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002365 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002366 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002367 }
2368}
2369
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002370void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002371 if (eventEntry.type == EventEntry::Type::FOCUS) {
2372 // Focus events are passed to apps, but do not represent user activity.
2373 return;
2374 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002375 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002376 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002377 if (focusedWindowHandle != nullptr) {
2378 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002379 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002380#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002381 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002382#endif
2383 return;
2384 }
2385 }
2386
2387 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002388 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002389 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002390 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2391 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002392 return;
2393 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002394
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002395 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002396 eventType = USER_ACTIVITY_EVENT_TOUCH;
2397 }
2398 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002399 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002400 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002401 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2402 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002403 return;
2404 }
2405 eventType = USER_ACTIVITY_EVENT_BUTTON;
2406 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002407 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002408 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002409 case EventEntry::Type::CONFIGURATION_CHANGED:
2410 case EventEntry::Type::DEVICE_RESET: {
2411 LOG_ALWAYS_FATAL("%s events are not user activity",
2412 EventEntry::typeToString(eventEntry.type));
2413 break;
2414 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002415 }
2416
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002417 std::unique_ptr<CommandEntry> commandEntry =
2418 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002419 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002420 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002421 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002422}
2423
2424void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002425 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002426 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002427 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002428 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002429 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002430 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002431 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002432 ATRACE_NAME(message.c_str());
2433 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002434#if DEBUG_DISPATCH_CYCLE
2435 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002436 "globalScaleFactor=%f, pointerIds=0x%x %s",
2437 connection->getInputChannelName().c_str(), inputTarget.flags,
2438 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2439 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002440#endif
2441
2442 // Skip this event if the connection status is not normal.
2443 // We don't want to enqueue additional outbound events if the connection is broken.
2444 if (connection->status != Connection::STATUS_NORMAL) {
2445#if DEBUG_DISPATCH_CYCLE
2446 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002447 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002448#endif
2449 return;
2450 }
2451
2452 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002453 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2454 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2455 "Entry type %s should not have FLAG_SPLIT",
2456 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002457
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002458 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002459 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002460 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002461 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002462 if (!splitMotionEntry) {
2463 return; // split event was dropped
2464 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002465 if (DEBUG_FOCUS) {
2466 ALOGD("channel '%s' ~ Split motion event.",
2467 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002468 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002469 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002470 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2471 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002472 return;
2473 }
2474 }
2475
2476 // Not splitting. Enqueue dispatch entries for the event as is.
2477 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2478}
2479
2480void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002481 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002482 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002483 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002484 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002485 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002486 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002487 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002488 ATRACE_NAME(message.c_str());
2489 }
2490
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002491 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002492
2493 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002494 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002495 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002496 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002497 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002498 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002499 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002500 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002501 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002502 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002503 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002504 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002505 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002506
2507 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002508 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002509 startDispatchCycleLocked(currentTime, connection);
2510 }
2511}
2512
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002513void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002514 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002515 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002516 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002517 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002518 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2519 connection->getInputChannelName().c_str(),
2520 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002521 ATRACE_NAME(message.c_str());
2522 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002523 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002524 if (!(inputTargetFlags & dispatchMode)) {
2525 return;
2526 }
2527 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2528
2529 // This is a new event.
2530 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002531 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002532 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002533
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002534 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2535 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002536 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002537 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002538 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002539 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002540 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002541 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002542 dispatchEntry->resolvedAction = keyEntry.action;
2543 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002544
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002545 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2546 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002547#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002548 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2549 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002550#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002551 return; // skip the inconsistent event
2552 }
2553 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002554 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002555
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002556 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002557 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002558 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2559 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2560 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2561 static_cast<int32_t>(IdGenerator::Source::OTHER);
2562 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002563 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2564 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2565 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2566 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2567 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2568 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2569 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2570 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2571 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2572 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2573 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002574 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002575 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002576 }
2577 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002578 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2579 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002580#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002581 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2582 "event",
2583 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002584#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002585 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2586 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002587
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002588 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002589 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2590 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2591 }
2592 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2593 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2594 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002595
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002596 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2597 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002598#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002599 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2600 "event",
2601 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002602#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002603 return; // skip the inconsistent event
2604 }
2605
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002606 dispatchEntry->resolvedEventId =
2607 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2608 ? mIdGenerator.nextId()
2609 : motionEntry.id;
2610 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2611 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2612 ") to MotionEvent(id=0x%" PRIx32 ").",
2613 motionEntry.id, dispatchEntry->resolvedEventId);
2614 ATRACE_NAME(message.c_str());
2615 }
2616
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002617 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002618 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002619
2620 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002621 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002622 case EventEntry::Type::FOCUS: {
2623 break;
2624 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002625 case EventEntry::Type::CONFIGURATION_CHANGED:
2626 case EventEntry::Type::DEVICE_RESET: {
2627 LOG_ALWAYS_FATAL("%s events should not go to apps",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002628 EventEntry::typeToString(newEntry.type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002629 break;
2630 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002631 }
2632
2633 // Remember that we are waiting for this dispatch to complete.
2634 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002635 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002636 }
2637
2638 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002639 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002640 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002641}
2642
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002643/**
2644 * This function is purely for debugging. It helps us understand where the user interaction
2645 * was taking place. For example, if user is touching launcher, we will see a log that user
2646 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2647 * We will see both launcher and wallpaper in that list.
2648 * Once the interaction with a particular set of connections starts, no new logs will be printed
2649 * until the set of interacted connections changes.
2650 *
2651 * The following items are skipped, to reduce the logspam:
2652 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2653 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2654 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2655 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2656 * Both of those ACTION_UP events would not be logged
2657 * Monitors (both gesture and global): any gesture monitors or global monitors receiving events
2658 * will not be logged. This is omitted to reduce the amount of data printed.
2659 * If you see <none>, it's likely that one of the gesture monitors pilfered the event, and therefore
2660 * gesture monitor is the only connection receiving the remainder of the gesture.
2661 */
2662void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2663 const std::vector<InputTarget>& targets) {
2664 // Skip ACTION_UP events, and all events other than keys and motions
2665 if (entry.type == EventEntry::Type::KEY) {
2666 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2667 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2668 return;
2669 }
2670 } else if (entry.type == EventEntry::Type::MOTION) {
2671 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2672 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2673 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2674 return;
2675 }
2676 } else {
2677 return; // Not a key or a motion
2678 }
2679
2680 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2681 std::vector<sp<Connection>> newConnections;
2682 for (const InputTarget& target : targets) {
2683 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2684 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2685 continue; // Skip windows that receive ACTION_OUTSIDE
2686 }
2687
2688 sp<IBinder> token = target.inputChannel->getConnectionToken();
2689 sp<Connection> connection = getConnectionLocked(token);
2690 if (connection == nullptr || connection->monitor) {
2691 continue; // We only need to keep track of the non-monitor connections.
2692 }
2693 newConnectionTokens.insert(std::move(token));
2694 newConnections.emplace_back(connection);
2695 }
2696 if (newConnectionTokens == mInteractionConnectionTokens) {
2697 return; // no change
2698 }
2699 mInteractionConnectionTokens = newConnectionTokens;
2700
2701 std::string windowList;
2702 for (const sp<Connection>& connection : newConnections) {
2703 windowList += connection->getWindowName() + ", ";
2704 }
2705 std::string message = "Interaction with windows: " + windowList;
2706 if (windowList.empty()) {
2707 message += "<none>";
2708 }
2709 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2710}
2711
chaviwfd6d3512019-03-25 13:23:49 -07002712void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002713 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002714 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002715 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2716 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002717 return;
2718 }
2719
Vishnu Nairad321cd2020-08-20 16:40:21 -07002720 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
2721 if (focusedToken == token) {
2722 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002723 return;
2724 }
2725
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002726 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2727 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002728 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002729 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002730}
2731
2732void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002733 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002734 if (ATRACE_ENABLED()) {
2735 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002736 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002737 ATRACE_NAME(message.c_str());
2738 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002739#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002740 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002741#endif
2742
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002743 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2744 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002745 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002746 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002747 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002748 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002749
2750 // Publish the event.
2751 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002752 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
2753 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002754 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002755 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2756 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002757
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002758 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002759 status = connection->inputPublisher
2760 .publishKeyEvent(dispatchEntry->seq,
2761 dispatchEntry->resolvedEventId, keyEntry.deviceId,
2762 keyEntry.source, keyEntry.displayId,
2763 std::move(hmac), dispatchEntry->resolvedAction,
2764 dispatchEntry->resolvedFlags, keyEntry.keyCode,
2765 keyEntry.scanCode, keyEntry.metaState,
2766 keyEntry.repeatCount, keyEntry.downTime,
2767 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002768 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002769 }
2770
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002771 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002772 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002773
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002774 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002775 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002776
chaviw82357092020-01-28 13:13:06 -08002777 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002778 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002779 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2780 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002781 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002782 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
2783 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002784 // Don't apply window scale here since we don't want scale to affect raw
2785 // coordinates. The scale will be sent back to the client and applied
2786 // later when requesting relative coordinates.
2787 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2788 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002789 }
2790 usingCoords = scaledCoords;
2791 }
2792 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002793 // We don't want the dispatch target to know.
2794 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002795 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002796 scaledCoords[i].clear();
2797 }
2798 usingCoords = scaledCoords;
2799 }
2800 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002801
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002802 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002803
2804 // Publish the motion event.
2805 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002806 .publishMotionEvent(dispatchEntry->seq,
2807 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002808 motionEntry.deviceId, motionEntry.source,
2809 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002810 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002811 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002812 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002813 motionEntry.edgeFlags, motionEntry.metaState,
2814 motionEntry.buttonState,
2815 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07002816 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002817 motionEntry.xPrecision, motionEntry.yPrecision,
2818 motionEntry.xCursorPosition,
2819 motionEntry.yCursorPosition,
2820 motionEntry.downTime, motionEntry.eventTime,
2821 motionEntry.pointerCount,
2822 motionEntry.pointerProperties, usingCoords);
2823 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002824 break;
2825 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002826 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002827 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002828 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002829 focusEntry.id,
2830 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002831 mInTouchMode);
2832 break;
2833 }
2834
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002835 case EventEntry::Type::CONFIGURATION_CHANGED:
2836 case EventEntry::Type::DEVICE_RESET: {
2837 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002838 EventEntry::typeToString(eventEntry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002839 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002840 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002841 }
2842
2843 // Check the result.
2844 if (status) {
2845 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002846 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002847 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002848 "This is unexpected because the wait queue is empty, so the pipe "
2849 "should be empty and we shouldn't have any problems writing an "
2850 "event to it, status=%d",
2851 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002852 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2853 } else {
2854 // Pipe is full and we are waiting for the app to finish process some events
2855 // before sending more events to it.
2856#if DEBUG_DISPATCH_CYCLE
2857 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002858 "waiting for the application to catch up",
2859 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002860#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08002861 }
2862 } else {
2863 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002864 "status=%d",
2865 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002866 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2867 }
2868 return;
2869 }
2870
2871 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002872 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2873 connection->outboundQueue.end(),
2874 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002875 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002876 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002877 if (connection->responsive) {
2878 mAnrTracker.insert(dispatchEntry->timeoutTime,
2879 connection->inputChannel->getConnectionToken());
2880 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002881 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002882 }
2883}
2884
chaviw09c8d2d2020-08-24 15:48:26 -07002885std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
2886 size_t size;
2887 switch (event.type) {
2888 case VerifiedInputEvent::Type::KEY: {
2889 size = sizeof(VerifiedKeyEvent);
2890 break;
2891 }
2892 case VerifiedInputEvent::Type::MOTION: {
2893 size = sizeof(VerifiedMotionEvent);
2894 break;
2895 }
2896 }
2897 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
2898 return mHmacKeyManager.sign(start, size);
2899}
2900
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002901const std::array<uint8_t, 32> InputDispatcher::getSignature(
2902 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
2903 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
2904 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
2905 // Only sign events up and down events as the purely move events
2906 // are tied to their up/down counterparts so signing would be redundant.
2907 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
2908 verifiedEvent.actionMasked = actionMasked;
2909 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07002910 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002911 }
2912 return INVALID_HMAC;
2913}
2914
2915const std::array<uint8_t, 32> InputDispatcher::getSignature(
2916 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
2917 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
2918 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
2919 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07002920 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002921}
2922
Michael Wrightd02c5b62014-02-10 15:10:22 -08002923void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002924 const sp<Connection>& connection, uint32_t seq,
2925 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002926#if DEBUG_DISPATCH_CYCLE
2927 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002928 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002929#endif
2930
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002931 if (connection->status == Connection::STATUS_BROKEN ||
2932 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002933 return;
2934 }
2935
2936 // Notify other system components and prepare to start the next dispatch cycle.
2937 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2938}
2939
2940void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002941 const sp<Connection>& connection,
2942 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002943#if DEBUG_DISPATCH_CYCLE
2944 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002945 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002946#endif
2947
2948 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002949 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002950 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002951 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002952 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002953
2954 // The connection appears to be unrecoverably broken.
2955 // Ignore already broken or zombie connections.
2956 if (connection->status == Connection::STATUS_NORMAL) {
2957 connection->status = Connection::STATUS_BROKEN;
2958
2959 if (notify) {
2960 // Notify other system components.
2961 onDispatchCycleBrokenLocked(currentTime, connection);
2962 }
2963 }
2964}
2965
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002966void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2967 while (!queue.empty()) {
2968 DispatchEntry* dispatchEntry = queue.front();
2969 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002970 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002971 }
2972}
2973
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002974void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002975 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002976 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002977 }
2978 delete dispatchEntry;
2979}
2980
2981int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2982 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2983
2984 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002985 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002986
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002987 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002988 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002989 "fd=%d, events=0x%x",
2990 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002991 return 0; // remove the callback
2992 }
2993
2994 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002995 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002996 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2997 if (!(events & ALOOPER_EVENT_INPUT)) {
2998 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002999 "events=0x%x",
3000 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003001 return 1;
3002 }
3003
3004 nsecs_t currentTime = now();
3005 bool gotOne = false;
3006 status_t status;
3007 for (;;) {
3008 uint32_t seq;
3009 bool handled;
3010 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
3011 if (status) {
3012 break;
3013 }
3014 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
3015 gotOne = true;
3016 }
3017 if (gotOne) {
3018 d->runCommandsLockedInterruptible();
3019 if (status == WOULD_BLOCK) {
3020 return 1;
3021 }
3022 }
3023
3024 notify = status != DEAD_OBJECT || !connection->monitor;
3025 if (notify) {
3026 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003027 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003028 }
3029 } else {
3030 // Monitor channels are never explicitly unregistered.
3031 // We do it automatically when the remote endpoint is closed so don't warn
3032 // about them.
arthurhungd352cb32020-04-28 17:09:28 +08003033 const bool stillHaveWindowHandle =
3034 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3035 nullptr;
3036 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003037 if (notify) {
3038 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003039 "events=0x%x",
3040 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003041 }
3042 }
3043
Garfield Tan15601662020-09-22 15:32:38 -07003044 // Remove the channel.
3045 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003046 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003047 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003048}
3049
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003050void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003051 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003052 for (const auto& pair : mConnectionsByFd) {
3053 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003054 }
3055}
3056
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003057void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003058 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003059 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3060 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3061}
3062
3063void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3064 const CancelationOptions& options,
3065 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3066 for (const auto& it : monitorsByDisplay) {
3067 const std::vector<Monitor>& monitors = it.second;
3068 for (const Monitor& monitor : monitors) {
3069 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003070 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003071 }
3072}
3073
Michael Wrightd02c5b62014-02-10 15:10:22 -08003074void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003075 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003076 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003077 if (connection == nullptr) {
3078 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003079 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003080
3081 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003082}
3083
3084void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3085 const sp<Connection>& connection, const CancelationOptions& options) {
3086 if (connection->status == Connection::STATUS_BROKEN) {
3087 return;
3088 }
3089
3090 nsecs_t currentTime = now();
3091
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003092 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003093 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003094
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003095 if (cancelationEvents.empty()) {
3096 return;
3097 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003098#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003099 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3100 "with reality: %s, mode=%d.",
3101 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3102 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003103#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003104
3105 InputTarget target;
3106 sp<InputWindowHandle> windowHandle =
3107 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3108 if (windowHandle != nullptr) {
3109 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003110 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003111 target.globalScaleFactor = windowInfo->globalScaleFactor;
3112 }
3113 target.inputChannel = connection->inputChannel;
3114 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3115
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003116 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003117 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003118 switch (cancelationEventEntry->type) {
3119 case EventEntry::Type::KEY: {
3120 logOutboundKeyDetails("cancel - ",
3121 static_cast<const KeyEntry&>(*cancelationEventEntry));
3122 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003123 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003124 case EventEntry::Type::MOTION: {
3125 logOutboundMotionDetails("cancel - ",
3126 static_cast<const MotionEntry&>(*cancelationEventEntry));
3127 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003128 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003129 case EventEntry::Type::FOCUS: {
3130 LOG_ALWAYS_FATAL("Canceling focus events is not supported");
3131 break;
3132 }
3133 case EventEntry::Type::CONFIGURATION_CHANGED:
3134 case EventEntry::Type::DEVICE_RESET: {
3135 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3136 EventEntry::typeToString(cancelationEventEntry->type));
3137 break;
3138 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003139 }
3140
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003141 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3142 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003143 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003144
3145 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003146}
3147
Svet Ganov5d3bc372020-01-26 23:11:07 -08003148void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3149 const sp<Connection>& connection) {
3150 if (connection->status == Connection::STATUS_BROKEN) {
3151 return;
3152 }
3153
3154 nsecs_t currentTime = now();
3155
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003156 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003157 connection->inputState.synthesizePointerDownEvents(currentTime);
3158
3159 if (downEvents.empty()) {
3160 return;
3161 }
3162
3163#if DEBUG_OUTBOUND_EVENT_DETAILS
3164 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3165 connection->getInputChannelName().c_str(), downEvents.size());
3166#endif
3167
3168 InputTarget target;
3169 sp<InputWindowHandle> windowHandle =
3170 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3171 if (windowHandle != nullptr) {
3172 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003173 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003174 target.globalScaleFactor = windowInfo->globalScaleFactor;
3175 }
3176 target.inputChannel = connection->inputChannel;
3177 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3178
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003179 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003180 switch (downEventEntry->type) {
3181 case EventEntry::Type::MOTION: {
3182 logOutboundMotionDetails("down - ",
3183 static_cast<const MotionEntry&>(*downEventEntry));
3184 break;
3185 }
3186
3187 case EventEntry::Type::KEY:
3188 case EventEntry::Type::FOCUS:
3189 case EventEntry::Type::CONFIGURATION_CHANGED:
3190 case EventEntry::Type::DEVICE_RESET: {
3191 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3192 EventEntry::typeToString(downEventEntry->type));
3193 break;
3194 }
3195 }
3196
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003197 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3198 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003199 }
3200
3201 startDispatchCycleLocked(currentTime, connection);
3202}
3203
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003204std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3205 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003206 ALOG_ASSERT(pointerIds.value != 0);
3207
3208 uint32_t splitPointerIndexMap[MAX_POINTERS];
3209 PointerProperties splitPointerProperties[MAX_POINTERS];
3210 PointerCoords splitPointerCoords[MAX_POINTERS];
3211
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003212 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003213 uint32_t splitPointerCount = 0;
3214
3215 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003216 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003217 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003218 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003219 uint32_t pointerId = uint32_t(pointerProperties.id);
3220 if (pointerIds.hasBit(pointerId)) {
3221 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3222 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3223 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003224 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003225 splitPointerCount += 1;
3226 }
3227 }
3228
3229 if (splitPointerCount != pointerIds.count()) {
3230 // This is bad. We are missing some of the pointers that we expected to deliver.
3231 // Most likely this indicates that we received an ACTION_MOVE events that has
3232 // different pointer ids than we expected based on the previous ACTION_DOWN
3233 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3234 // in this way.
3235 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003236 "we expected there to be %d pointers. This probably means we received "
3237 "a broken sequence of pointer ids from the input device.",
3238 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003239 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003240 }
3241
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003242 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003243 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003244 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3245 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003246 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3247 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003248 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003249 uint32_t pointerId = uint32_t(pointerProperties.id);
3250 if (pointerIds.hasBit(pointerId)) {
3251 if (pointerIds.count() == 1) {
3252 // The first/last pointer went down/up.
3253 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003254 ? AMOTION_EVENT_ACTION_DOWN
3255 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003256 } else {
3257 // A secondary pointer went down/up.
3258 uint32_t splitPointerIndex = 0;
3259 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3260 splitPointerIndex += 1;
3261 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003262 action = maskedAction |
3263 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003264 }
3265 } else {
3266 // An unrelated pointer changed.
3267 action = AMOTION_EVENT_ACTION_MOVE;
3268 }
3269 }
3270
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003271 int32_t newId = mIdGenerator.nextId();
3272 if (ATRACE_ENABLED()) {
3273 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3274 ") to MotionEvent(id=0x%" PRIx32 ").",
3275 originalMotionEntry.id, newId);
3276 ATRACE_NAME(message.c_str());
3277 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003278 std::unique_ptr<MotionEntry> splitMotionEntry =
3279 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3280 originalMotionEntry.deviceId, originalMotionEntry.source,
3281 originalMotionEntry.displayId,
3282 originalMotionEntry.policyFlags, action,
3283 originalMotionEntry.actionButton,
3284 originalMotionEntry.flags, originalMotionEntry.metaState,
3285 originalMotionEntry.buttonState,
3286 originalMotionEntry.classification,
3287 originalMotionEntry.edgeFlags,
3288 originalMotionEntry.xPrecision,
3289 originalMotionEntry.yPrecision,
3290 originalMotionEntry.xCursorPosition,
3291 originalMotionEntry.yCursorPosition,
3292 originalMotionEntry.downTime, splitPointerCount,
3293 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003294
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003295 if (originalMotionEntry.injectionState) {
3296 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003297 splitMotionEntry->injectionState->refCount += 1;
3298 }
3299
3300 return splitMotionEntry;
3301}
3302
3303void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3304#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003305 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003306#endif
3307
3308 bool needWake;
3309 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003310 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003311
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003312 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3313 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3314 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003315 } // release lock
3316
3317 if (needWake) {
3318 mLooper->wake();
3319 }
3320}
3321
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003322/**
3323 * If one of the meta shortcuts is detected, process them here:
3324 * Meta + Backspace -> generate BACK
3325 * Meta + Enter -> generate HOME
3326 * This will potentially overwrite keyCode and metaState.
3327 */
3328void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003329 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003330 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3331 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3332 if (keyCode == AKEYCODE_DEL) {
3333 newKeyCode = AKEYCODE_BACK;
3334 } else if (keyCode == AKEYCODE_ENTER) {
3335 newKeyCode = AKEYCODE_HOME;
3336 }
3337 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003338 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003339 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003340 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003341 keyCode = newKeyCode;
3342 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3343 }
3344 } else if (action == AKEY_EVENT_ACTION_UP) {
3345 // In order to maintain a consistent stream of up and down events, check to see if the key
3346 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3347 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003348 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003349 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003350 auto replacementIt = mReplacedKeys.find(replacement);
3351 if (replacementIt != mReplacedKeys.end()) {
3352 keyCode = replacementIt->second;
3353 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003354 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3355 }
3356 }
3357}
3358
Michael Wrightd02c5b62014-02-10 15:10:22 -08003359void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3360#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003361 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3362 "policyFlags=0x%x, action=0x%x, "
3363 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3364 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3365 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3366 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003367#endif
3368 if (!validateKeyEvent(args->action)) {
3369 return;
3370 }
3371
3372 uint32_t policyFlags = args->policyFlags;
3373 int32_t flags = args->flags;
3374 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003375 // InputDispatcher tracks and generates key repeats on behalf of
3376 // whatever notifies it, so repeatCount should always be set to 0
3377 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003378 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3379 policyFlags |= POLICY_FLAG_VIRTUAL;
3380 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3381 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003382 if (policyFlags & POLICY_FLAG_FUNCTION) {
3383 metaState |= AMETA_FUNCTION_ON;
3384 }
3385
3386 policyFlags |= POLICY_FLAG_TRUSTED;
3387
Michael Wright78f24442014-08-06 15:55:28 -07003388 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003389 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003390
Michael Wrightd02c5b62014-02-10 15:10:22 -08003391 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003392 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003393 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3394 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003395
Michael Wright2b3c3302018-03-02 17:19:13 +00003396 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003397 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003398 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3399 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003400 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003401 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003402
Michael Wrightd02c5b62014-02-10 15:10:22 -08003403 bool needWake;
3404 { // acquire lock
3405 mLock.lock();
3406
3407 if (shouldSendKeyToInputFilterLocked(args)) {
3408 mLock.unlock();
3409
3410 policyFlags |= POLICY_FLAG_FILTERED;
3411 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3412 return; // event was consumed by the filter
3413 }
3414
3415 mLock.lock();
3416 }
3417
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003418 std::unique_ptr<KeyEntry> newEntry =
3419 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3420 args->displayId, policyFlags, args->action, flags,
3421 keyCode, args->scanCode, metaState, repeatCount,
3422 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003423
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003424 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003425 mLock.unlock();
3426 } // release lock
3427
3428 if (needWake) {
3429 mLooper->wake();
3430 }
3431}
3432
3433bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3434 return mInputFilterEnabled;
3435}
3436
3437void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3438#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003439 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3440 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003441 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3442 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003443 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003444 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3445 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3446 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3447 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003448 for (uint32_t i = 0; i < args->pointerCount; i++) {
3449 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003450 "x=%f, y=%f, pressure=%f, size=%f, "
3451 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3452 "orientation=%f",
3453 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3454 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3455 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3456 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3457 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3458 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3459 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3460 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3461 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3462 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003463 }
3464#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003465 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3466 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003467 return;
3468 }
3469
3470 uint32_t policyFlags = args->policyFlags;
3471 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003472
3473 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003474 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003475 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3476 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003477 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003478 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003479
3480 bool needWake;
3481 { // acquire lock
3482 mLock.lock();
3483
3484 if (shouldSendMotionToInputFilterLocked(args)) {
3485 mLock.unlock();
3486
3487 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003488 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003489 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3490 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003491 args->metaState, args->buttonState, args->classification, transform,
3492 args->xPrecision, args->yPrecision, args->xCursorPosition,
3493 args->yCursorPosition, args->downTime, args->eventTime,
3494 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003495
3496 policyFlags |= POLICY_FLAG_FILTERED;
3497 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3498 return; // event was consumed by the filter
3499 }
3500
3501 mLock.lock();
3502 }
3503
3504 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003505 std::unique_ptr<MotionEntry> newEntry =
3506 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3507 args->source, args->displayId, policyFlags,
3508 args->action, args->actionButton, args->flags,
3509 args->metaState, args->buttonState,
3510 args->classification, args->edgeFlags,
3511 args->xPrecision, args->yPrecision,
3512 args->xCursorPosition, args->yCursorPosition,
3513 args->downTime, args->pointerCount,
3514 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003515
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003516 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003517 mLock.unlock();
3518 } // release lock
3519
3520 if (needWake) {
3521 mLooper->wake();
3522 }
3523}
3524
3525bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003526 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003527}
3528
3529void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3530#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003531 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003532 "switchMask=0x%08x",
3533 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003534#endif
3535
3536 uint32_t policyFlags = args->policyFlags;
3537 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003538 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003539}
3540
3541void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3542#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003543 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3544 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003545#endif
3546
3547 bool needWake;
3548 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003549 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003550
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003551 std::unique_ptr<DeviceResetEntry> newEntry =
3552 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3553 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003554 } // release lock
3555
3556 if (needWake) {
3557 mLooper->wake();
3558 }
3559}
3560
Prabir Pradhan7e186182020-11-10 13:56:45 -08003561void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3562#if DEBUG_INBOUND_EVENT_DETAILS
3563 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3564 args->enabled ? "true" : "false");
3565#endif
3566
3567 // TODO(prabirmsp): Implement.
3568}
3569
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003570InputEventInjectionResult InputDispatcher::injectInputEvent(
3571 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3572 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003573#if DEBUG_INBOUND_EVENT_DETAILS
3574 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003575 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3576 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003577#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003578 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003579
3580 policyFlags |= POLICY_FLAG_INJECTED;
3581 if (hasInjectionPermission(injectorPid, injectorUid)) {
3582 policyFlags |= POLICY_FLAG_TRUSTED;
3583 }
3584
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003585 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003586 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003587 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003588 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3589 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003590 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003591 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003592 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003593
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003594 int32_t flags = incomingKey.getFlags();
3595 int32_t keyCode = incomingKey.getKeyCode();
3596 int32_t metaState = incomingKey.getMetaState();
3597 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003598 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003599 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003600 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003601 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3602 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3603 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003604
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003605 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3606 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003607 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003608
3609 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3610 android::base::Timer t;
3611 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3612 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3613 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3614 std::to_string(t.duration().count()).c_str());
3615 }
3616 }
3617
3618 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003619 std::unique_ptr<KeyEntry> injectedEntry =
3620 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3621 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3622 incomingKey.getDisplayId(), policyFlags, action,
3623 flags, keyCode, incomingKey.getScanCode(), metaState,
3624 incomingKey.getRepeatCount(),
3625 incomingKey.getDownTime());
3626 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003627 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003628 }
3629
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003630 case AINPUT_EVENT_TYPE_MOTION: {
3631 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3632 int32_t action = motionEvent->getAction();
3633 size_t pointerCount = motionEvent->getPointerCount();
3634 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3635 int32_t actionButton = motionEvent->getActionButton();
3636 int32_t displayId = motionEvent->getDisplayId();
3637 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003638 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003639 }
3640
3641 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3642 nsecs_t eventTime = motionEvent->getEventTime();
3643 android::base::Timer t;
3644 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3645 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3646 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3647 std::to_string(t.duration().count()).c_str());
3648 }
3649 }
3650
3651 mLock.lock();
3652 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3653 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003654 std::unique_ptr<MotionEntry> injectedEntry =
3655 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3656 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3657 motionEvent->getDisplayId(), policyFlags, action,
3658 actionButton, motionEvent->getFlags(),
3659 motionEvent->getMetaState(),
3660 motionEvent->getButtonState(),
3661 motionEvent->getClassification(),
3662 motionEvent->getEdgeFlags(),
3663 motionEvent->getXPrecision(),
3664 motionEvent->getYPrecision(),
3665 motionEvent->getRawXCursorPosition(),
3666 motionEvent->getRawYCursorPosition(),
3667 motionEvent->getDownTime(),
3668 uint32_t(pointerCount), pointerProperties,
3669 samplePointerCoords, motionEvent->getXOffset(),
3670 motionEvent->getYOffset());
3671 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003672 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3673 sampleEventTimes += 1;
3674 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003675 std::unique_ptr<MotionEntry> nextInjectedEntry =
3676 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3677 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3678 motionEvent->getDisplayId(), policyFlags,
3679 action, actionButton, motionEvent->getFlags(),
3680 motionEvent->getMetaState(),
3681 motionEvent->getButtonState(),
3682 motionEvent->getClassification(),
3683 motionEvent->getEdgeFlags(),
3684 motionEvent->getXPrecision(),
3685 motionEvent->getYPrecision(),
3686 motionEvent->getRawXCursorPosition(),
3687 motionEvent->getRawYCursorPosition(),
3688 motionEvent->getDownTime(),
3689 uint32_t(pointerCount), pointerProperties,
3690 samplePointerCoords,
3691 motionEvent->getXOffset(),
3692 motionEvent->getYOffset());
3693 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003694 }
3695 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003696 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003697
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003698 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003699 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003700 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003701 }
3702
3703 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003704 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003705 injectionState->injectionIsAsync = true;
3706 }
3707
3708 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003709 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003710
3711 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003712 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003713 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003714 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003715 }
3716
3717 mLock.unlock();
3718
3719 if (needWake) {
3720 mLooper->wake();
3721 }
3722
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003723 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003724 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003725 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003726
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003727 if (syncMode == InputEventInjectionSync::NONE) {
3728 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003729 } else {
3730 for (;;) {
3731 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003732 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003733 break;
3734 }
3735
3736 nsecs_t remainingTimeout = endTime - now();
3737 if (remainingTimeout <= 0) {
3738#if DEBUG_INJECTION
3739 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003740 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003741#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003742 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003743 break;
3744 }
3745
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003746 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003747 }
3748
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003749 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3750 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003751 while (injectionState->pendingForegroundDispatches != 0) {
3752#if DEBUG_INJECTION
3753 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003754 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003755#endif
3756 nsecs_t remainingTimeout = endTime - now();
3757 if (remainingTimeout <= 0) {
3758#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003759 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3760 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003761#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003762 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003763 break;
3764 }
3765
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003766 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003767 }
3768 }
3769 }
3770
3771 injectionState->release();
3772 } // release lock
3773
3774#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003775 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003776 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003777#endif
3778
3779 return injectionResult;
3780}
3781
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003782std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05003783 std::array<uint8_t, 32> calculatedHmac;
3784 std::unique_ptr<VerifiedInputEvent> result;
3785 switch (event.getType()) {
3786 case AINPUT_EVENT_TYPE_KEY: {
3787 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
3788 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
3789 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003790 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05003791 break;
3792 }
3793 case AINPUT_EVENT_TYPE_MOTION: {
3794 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
3795 VerifiedMotionEvent verifiedMotionEvent =
3796 verifiedMotionEventFromMotionEvent(motionEvent);
3797 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003798 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05003799 break;
3800 }
3801 default: {
3802 ALOGE("Cannot verify events of type %" PRId32, event.getType());
3803 return nullptr;
3804 }
3805 }
3806 if (calculatedHmac == INVALID_HMAC) {
3807 return nullptr;
3808 }
3809 if (calculatedHmac != event.getHmac()) {
3810 return nullptr;
3811 }
3812 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003813}
3814
Michael Wrightd02c5b62014-02-10 15:10:22 -08003815bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003816 return injectorUid == 0 ||
3817 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003818}
3819
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003820void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003821 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003822 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003823 if (injectionState) {
3824#if DEBUG_INJECTION
3825 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003826 "injectorPid=%d, injectorUid=%d",
3827 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003828#endif
3829
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003830 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003831 // Log the outcome since the injector did not wait for the injection result.
3832 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003833 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003834 ALOGV("Asynchronous input event injection succeeded.");
3835 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003836 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003837 ALOGW("Asynchronous input event injection failed.");
3838 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003839 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003840 ALOGW("Asynchronous input event injection permission denied.");
3841 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003842 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003843 ALOGW("Asynchronous input event injection timed out.");
3844 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003845 case InputEventInjectionResult::PENDING:
3846 ALOGE("Setting result to 'PENDING' for asynchronous injection");
3847 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848 }
3849 }
3850
3851 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003852 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003853 }
3854}
3855
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003856void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
3857 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003858 if (injectionState) {
3859 injectionState->pendingForegroundDispatches += 1;
3860 }
3861}
3862
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003863void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
3864 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865 if (injectionState) {
3866 injectionState->pendingForegroundDispatches -= 1;
3867
3868 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003869 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003870 }
3871 }
3872}
3873
Vishnu Nairad321cd2020-08-20 16:40:21 -07003874const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003875 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003876 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
3877 auto it = mWindowHandlesByDisplay.find(displayId);
3878 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08003879}
3880
Michael Wrightd02c5b62014-02-10 15:10:22 -08003881sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003882 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08003883 if (windowHandleToken == nullptr) {
3884 return nullptr;
3885 }
3886
Arthur Hungb92218b2018-08-14 12:00:21 +08003887 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003888 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003889 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003890 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003891 return windowHandle;
3892 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003893 }
3894 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003895 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003896}
3897
Vishnu Nairad321cd2020-08-20 16:40:21 -07003898sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
3899 int displayId) const {
3900 if (windowHandleToken == nullptr) {
3901 return nullptr;
3902 }
3903
3904 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3905 if (windowHandle->getToken() == windowHandleToken) {
3906 return windowHandle;
3907 }
3908 }
3909 return nullptr;
3910}
3911
3912sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
3913 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
3914 return getWindowHandleLocked(focusedToken, displayId);
3915}
3916
Mady Mellor017bcd12020-06-23 19:12:00 +00003917bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
3918 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003919 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00003920 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08003921 if (handle->getId() == windowHandle->getId() &&
3922 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00003923 if (windowHandle->getInfo()->displayId != it.first) {
3924 ALOGE("Found window %s in display %" PRId32
3925 ", but it should belong to display %" PRId32,
3926 windowHandle->getName().c_str(), it.first,
3927 windowHandle->getInfo()->displayId);
3928 }
3929 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08003930 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003931 }
3932 }
3933 return false;
3934}
3935
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05003936bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
3937 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
3938 const bool noInputChannel =
3939 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3940 if (connection != nullptr && noInputChannel) {
3941 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
3942 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
3943 return false;
3944 }
3945
3946 if (connection == nullptr) {
3947 if (!noInputChannel) {
3948 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
3949 }
3950 return false;
3951 }
3952 if (!connection->responsive) {
3953 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
3954 return false;
3955 }
3956 return true;
3957}
3958
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003959std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
3960 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07003961 size_t count = mInputChannelsByToken.count(token);
3962 if (count == 0) {
3963 return nullptr;
3964 }
3965 return mInputChannelsByToken.at(token);
3966}
3967
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003968void InputDispatcher::updateWindowHandlesForDisplayLocked(
3969 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3970 if (inputWindowHandles.empty()) {
3971 // Remove all handles on a display if there are no windows left.
3972 mWindowHandlesByDisplay.erase(displayId);
3973 return;
3974 }
3975
3976 // Since we compare the pointer of input window handles across window updates, we need
3977 // to make sure the handle object for the same window stays unchanged across updates.
3978 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003979 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003980 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003981 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003982 }
3983
3984 std::vector<sp<InputWindowHandle>> newHandles;
3985 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3986 if (!handle->updateInfo()) {
3987 // handle no longer valid
3988 continue;
3989 }
3990
3991 const InputWindowInfo* info = handle->getInfo();
3992 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3993 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3994 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01003995 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3996 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
3997 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003998 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003999 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004000 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004001 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004002 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004003 }
4004
4005 if (info->displayId != displayId) {
4006 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4007 handle->getName().c_str(), displayId, info->displayId);
4008 continue;
4009 }
4010
Robert Carredd13602020-04-13 17:24:34 -07004011 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4012 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004013 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004014 oldHandle->updateFrom(handle);
4015 newHandles.push_back(oldHandle);
4016 } else {
4017 newHandles.push_back(handle);
4018 }
4019 }
4020
4021 // Insert or replace
4022 mWindowHandlesByDisplay[displayId] = newHandles;
4023}
4024
Arthur Hung72d8dc32020-03-28 00:48:39 +00004025void InputDispatcher::setInputWindows(
4026 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4027 { // acquire lock
4028 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004029 for (const auto& [displayId, handles] : handlesPerDisplay) {
4030 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004031 }
4032 }
4033 // Wake up poll loop since it may need to make new input dispatching choices.
4034 mLooper->wake();
4035}
4036
Arthur Hungb92218b2018-08-14 12:00:21 +08004037/**
4038 * Called from InputManagerService, update window handle list by displayId that can receive input.
4039 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4040 * If set an empty list, remove all handles from the specific display.
4041 * For focused handle, check if need to change and send a cancel event to previous one.
4042 * For removed handle, check if need to send a cancel event if already in touch.
4043 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004044void InputDispatcher::setInputWindowsLocked(
4045 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004046 if (DEBUG_FOCUS) {
4047 std::string windowList;
4048 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4049 windowList += iwh->getName() + " ";
4050 }
4051 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4052 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004053
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004054 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4055 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4056 const bool noInputWindow =
4057 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4058 if (noInputWindow && window->getToken() != nullptr) {
4059 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4060 window->getName().c_str());
4061 window->releaseChannel();
4062 }
4063 }
4064
Arthur Hung72d8dc32020-03-28 00:48:39 +00004065 // Copy old handles for release if they are no longer present.
4066 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004067
Arthur Hung72d8dc32020-03-28 00:48:39 +00004068 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004069
Vishnu Nair958da932020-08-21 17:12:37 -07004070 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4071 if (mLastHoverWindowHandle &&
4072 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4073 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004074 mLastHoverWindowHandle = nullptr;
4075 }
4076
Vishnu Nair958da932020-08-21 17:12:37 -07004077 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4078 if (focusedToken) {
4079 FocusResult result = checkTokenFocusableLocked(focusedToken, displayId);
4080 if (result != FocusResult::OK) {
4081 onFocusChangedLocked(focusedToken, nullptr, displayId, typeToString(result));
4082 }
4083 }
4084
4085 std::optional<FocusRequest> focusRequest =
4086 getOptionalValueByKey(mPendingFocusRequests, displayId);
4087 if (focusRequest) {
4088 // If the window from the pending request is now visible, provide it focus.
4089 FocusResult result = handleFocusRequestLocked(*focusRequest);
4090 if (result != FocusResult::NOT_VISIBLE) {
4091 // Drop the request if we were able to change the focus or we cannot change
4092 // it for another reason.
4093 mPendingFocusRequests.erase(displayId);
4094 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004095 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004096
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004097 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4098 mTouchStatesByDisplay.find(displayId);
4099 if (stateIt != mTouchStatesByDisplay.end()) {
4100 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004101 for (size_t i = 0; i < state.windows.size();) {
4102 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004103 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004104 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004105 ALOGD("Touched window was removed: %s in display %" PRId32,
4106 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004107 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004108 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004109 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4110 if (touchedInputChannel != nullptr) {
4111 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4112 "touched window was removed");
4113 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004114 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004115 state.windows.erase(state.windows.begin() + i);
4116 } else {
4117 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004118 }
4119 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004120 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004121
Arthur Hung72d8dc32020-03-28 00:48:39 +00004122 // Release information for windows that are no longer present.
4123 // This ensures that unused input channels are released promptly.
4124 // Otherwise, they might stick around until the window handle is destroyed
4125 // which might not happen until the next GC.
4126 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004127 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004128 if (DEBUG_FOCUS) {
4129 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004130 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004131 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004132 // To avoid making too many calls into the compat framework, only
4133 // check for window flags when windows are going away.
4134 // TODO(b/157929241) : delete this. This is only needed temporarily
4135 // in order to gather some data about the flag usage
4136 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4137 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4138 oldWindowHandle->getName().c_str());
4139 if (mCompatService != nullptr) {
4140 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4141 oldWindowHandle->getInfo()->ownerUid);
4142 }
4143 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004144 }
chaviw291d88a2019-02-14 10:33:58 -08004145 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004146}
4147
4148void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004149 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004150 if (DEBUG_FOCUS) {
4151 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4152 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4153 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004154 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004155 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004156
Chris Yea209fde2020-07-22 13:54:51 -07004157 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004158 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004159
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004160 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4161 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004162 }
4163
Chris Yea209fde2020-07-22 13:54:51 -07004164 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004165 if (inputApplicationHandle != nullptr) {
4166 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4167 } else {
4168 mFocusedApplicationHandlesByDisplay.erase(displayId);
4169 }
4170
4171 // No matter what the old focused application was, stop waiting on it because it is
4172 // no longer focused.
4173 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004174 } // release lock
4175
4176 // Wake up poll loop since it may need to make new input dispatching choices.
4177 mLooper->wake();
4178}
4179
Tiger Huang721e26f2018-07-24 22:26:19 +08004180/**
4181 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4182 * the display not specified.
4183 *
4184 * We track any unreleased events for each window. If a window loses the ability to receive the
4185 * released event, we will send a cancel event to it. So when the focused display is changed, we
4186 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4187 * display. The display-specified events won't be affected.
4188 */
4189void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004190 if (DEBUG_FOCUS) {
4191 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4192 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004193 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004194 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004195
4196 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004197 sp<IBinder> oldFocusedWindowToken =
4198 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4199 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004200 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004201 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004202 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004203 CancelationOptions
4204 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4205 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004206 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004207 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4208 }
4209 }
4210 mFocusedDisplayId = displayId;
4211
Chris Ye3c2d6f52020-08-09 10:39:48 -07004212 // Find new focused window and validate
Vishnu Nairad321cd2020-08-20 16:40:21 -07004213 sp<IBinder> newFocusedWindowToken =
4214 getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4215 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004216
Vishnu Nairad321cd2020-08-20 16:40:21 -07004217 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004218 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004219 if (!mFocusedWindowTokenByDisplay.empty()) {
4220 ALOGE("But another display has a focused window\n%s",
4221 dumpFocusedWindowsLocked().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004222 }
4223 }
4224 }
4225
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004226 if (DEBUG_FOCUS) {
4227 logDispatchStateLocked();
4228 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004229 } // release lock
4230
4231 // Wake up poll loop since it may need to make new input dispatching choices.
4232 mLooper->wake();
4233}
4234
Michael Wrightd02c5b62014-02-10 15:10:22 -08004235void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004236 if (DEBUG_FOCUS) {
4237 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4238 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004239
4240 bool changed;
4241 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004242 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004243
4244 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4245 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004246 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004247 }
4248
4249 if (mDispatchEnabled && !enabled) {
4250 resetAndDropEverythingLocked("dispatcher is being disabled");
4251 }
4252
4253 mDispatchEnabled = enabled;
4254 mDispatchFrozen = frozen;
4255 changed = true;
4256 } else {
4257 changed = false;
4258 }
4259
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004260 if (DEBUG_FOCUS) {
4261 logDispatchStateLocked();
4262 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004263 } // release lock
4264
4265 if (changed) {
4266 // Wake up poll loop since it may need to make new input dispatching choices.
4267 mLooper->wake();
4268 }
4269}
4270
4271void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004272 if (DEBUG_FOCUS) {
4273 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4274 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004275
4276 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004277 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004278
4279 if (mInputFilterEnabled == enabled) {
4280 return;
4281 }
4282
4283 mInputFilterEnabled = enabled;
4284 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4285 } // release lock
4286
4287 // Wake up poll loop since there might be work to do to drop everything.
4288 mLooper->wake();
4289}
4290
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004291void InputDispatcher::setInTouchMode(bool inTouchMode) {
4292 std::scoped_lock lock(mLock);
4293 mInTouchMode = inTouchMode;
4294}
4295
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004296void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4297 if (opacity < 0 || opacity > 1) {
4298 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4299 return;
4300 }
4301
4302 std::scoped_lock lock(mLock);
4303 mMaximumObscuringOpacityForTouch = opacity;
4304}
4305
4306void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4307 std::scoped_lock lock(mLock);
4308 mBlockUntrustedTouchesMode = mode;
4309}
4310
chaviwfbe5d9c2018-12-26 12:23:37 -08004311bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4312 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004313 if (DEBUG_FOCUS) {
4314 ALOGD("Trivial transfer to same window.");
4315 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004316 return true;
4317 }
4318
Michael Wrightd02c5b62014-02-10 15:10:22 -08004319 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004320 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004321
chaviwfbe5d9c2018-12-26 12:23:37 -08004322 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4323 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004324 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004325 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004326 return false;
4327 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004328 if (DEBUG_FOCUS) {
4329 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4330 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4331 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004332 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004333 if (DEBUG_FOCUS) {
4334 ALOGD("Cannot transfer focus because windows are on different displays.");
4335 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004336 return false;
4337 }
4338
4339 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004340 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4341 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004342 for (size_t i = 0; i < state.windows.size(); i++) {
4343 const TouchedWindow& touchedWindow = state.windows[i];
4344 if (touchedWindow.windowHandle == fromWindowHandle) {
4345 int32_t oldTargetFlags = touchedWindow.targetFlags;
4346 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004347
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004348 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004349
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004350 int32_t newTargetFlags = oldTargetFlags &
4351 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4352 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004353 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004354
Jeff Brownf086ddb2014-02-11 14:28:48 -08004355 found = true;
4356 goto Found;
4357 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004358 }
4359 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004360 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004361
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004362 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004363 if (DEBUG_FOCUS) {
4364 ALOGD("Focus transfer failed because from window did not have focus.");
4365 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004366 return false;
4367 }
4368
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004369 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4370 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004371 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004372 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004373 CancelationOptions
4374 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4375 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004376 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004377 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004378 }
4379
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004380 if (DEBUG_FOCUS) {
4381 logDispatchStateLocked();
4382 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004383 } // release lock
4384
4385 // Wake up poll loop since it may need to make new input dispatching choices.
4386 mLooper->wake();
4387 return true;
4388}
4389
4390void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004391 if (DEBUG_FOCUS) {
4392 ALOGD("Resetting and dropping all events (%s).", reason);
4393 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004394
4395 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4396 synthesizeCancelationEventsForAllConnectionsLocked(options);
4397
4398 resetKeyRepeatLocked();
4399 releasePendingEventLocked();
4400 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004401 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004402
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004403 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004404 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004405 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004406 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004407}
4408
4409void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004410 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004411 dumpDispatchStateLocked(dump);
4412
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004413 std::istringstream stream(dump);
4414 std::string line;
4415
4416 while (std::getline(stream, line, '\n')) {
4417 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004418 }
4419}
4420
Vishnu Nairad321cd2020-08-20 16:40:21 -07004421std::string InputDispatcher::dumpFocusedWindowsLocked() {
4422 if (mFocusedWindowTokenByDisplay.empty()) {
4423 return INDENT "FocusedWindows: <none>\n";
4424 }
4425
4426 std::string dump;
4427 dump += INDENT "FocusedWindows:\n";
4428 for (auto& it : mFocusedWindowTokenByDisplay) {
4429 const int32_t displayId = it.first;
4430 const sp<InputWindowHandle> windowHandle = getFocusedWindowHandleLocked(displayId);
4431 if (windowHandle) {
4432 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
4433 windowHandle->getName().c_str());
4434 } else {
4435 dump += StringPrintf(INDENT2 "displayId=%" PRId32
4436 " has focused token without a window'\n",
4437 displayId);
4438 }
4439 }
4440 return dump;
4441}
4442
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004443std::string InputDispatcher::dumpPendingFocusRequestsLocked() {
4444 if (mPendingFocusRequests.empty()) {
4445 return INDENT "mPendingFocusRequests: <none>\n";
4446 }
4447
4448 std::string dump;
4449 dump += INDENT "mPendingFocusRequests:\n";
4450 for (const auto& [displayId, focusRequest] : mPendingFocusRequests) {
4451 // Rather than printing raw values for focusRequest.token and focusRequest.focusedToken,
4452 // try to resolve them to actual windows.
4453 std::string windowName = getConnectionNameLocked(focusRequest.token);
4454 std::string focusedWindowName = getConnectionNameLocked(focusRequest.focusedToken);
4455 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", token->%s, focusedToken->%s\n",
4456 displayId, windowName.c_str(), focusedWindowName.c_str());
4457 }
4458 return dump;
4459}
4460
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004461void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004462 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4463 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4464 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004465 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004466
Tiger Huang721e26f2018-07-24 22:26:19 +08004467 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4468 dump += StringPrintf(INDENT "FocusedApplications:\n");
4469 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4470 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004471 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004472 const std::chrono::duration timeout =
4473 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004474 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004475 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004476 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004477 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004478 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004479 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004480 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004481
Vishnu Nairad321cd2020-08-20 16:40:21 -07004482 dump += dumpFocusedWindowsLocked();
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004483 dump += dumpPendingFocusRequestsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004484
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004485 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004486 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004487 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4488 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004489 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004490 state.displayId, toString(state.down), toString(state.split),
4491 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004492 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004493 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004494 for (size_t i = 0; i < state.windows.size(); i++) {
4495 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004496 dump += StringPrintf(INDENT4
4497 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4498 i, touchedWindow.windowHandle->getName().c_str(),
4499 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004500 }
4501 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004502 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004503 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004504 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004505 dump += INDENT3 "Portal windows:\n";
4506 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004507 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004508 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4509 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004510 }
4511 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004512 }
4513 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004514 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004515 }
4516
Arthur Hungb92218b2018-08-14 12:00:21 +08004517 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004518 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004519 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004520 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004521 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004522 dump += INDENT2 "Windows:\n";
4523 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004524 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004525 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004526
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004527 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004528 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004529 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004530 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004531 "frame=[%d,%d][%d,%d], globalScale=%f, "
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004532 "applicationInfo=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004533 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004534 i, windowInfo->name.c_str(), windowInfo->id,
4535 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004536 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004537 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004538 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004539 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004540 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004541 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004542 windowInfo->frameLeft, windowInfo->frameTop,
4543 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004544 windowInfo->globalScaleFactor,
4545 windowInfo->applicationInfo.name.c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004546 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004547 dump += StringPrintf(", inputFeatures=%s",
4548 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004549 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004550 "ms, trustedOverlay=%s, hasToken=%s, "
4551 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004552 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004553 millis(windowInfo->dispatchingTimeout),
4554 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004555 toString(windowInfo->token != nullptr),
4556 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004557 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004558 }
4559 } else {
4560 dump += INDENT2 "Windows: <none>\n";
4561 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004562 }
4563 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004564 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004565 }
4566
Michael Wright3dd60e22019-03-27 22:06:44 +00004567 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004568 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004569 const std::vector<Monitor>& monitors = it.second;
4570 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4571 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004572 }
4573 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004574 const std::vector<Monitor>& monitors = it.second;
4575 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4576 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004577 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004578 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004579 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004580 }
4581
4582 nsecs_t currentTime = now();
4583
4584 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004585 if (!mRecentQueue.empty()) {
4586 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004587 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004588 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004589 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004590 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004591 }
4592 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004593 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004594 }
4595
4596 // Dump event currently being dispatched.
4597 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004598 dump += INDENT "PendingEvent:\n";
4599 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004600 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004601 dump += StringPrintf(", age=%" PRId64 "ms\n",
4602 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004603 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004604 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004605 }
4606
4607 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004608 if (!mInboundQueue.empty()) {
4609 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004610 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004611 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004612 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004613 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004614 }
4615 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004616 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004617 }
4618
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004619 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004620 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004621 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4622 const KeyReplacement& replacement = pair.first;
4623 int32_t newKeyCode = pair.second;
4624 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004625 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004626 }
4627 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004628 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004629 }
4630
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004631 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004632 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004633 for (const auto& pair : mConnectionsByFd) {
4634 const sp<Connection>& connection = pair.second;
4635 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004636 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004637 pair.first, connection->getInputChannelName().c_str(),
4638 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004639 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004640
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004641 if (!connection->outboundQueue.empty()) {
4642 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4643 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004644 dump += dumpQueue(connection->outboundQueue, currentTime);
4645
Michael Wrightd02c5b62014-02-10 15:10:22 -08004646 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004647 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004648 }
4649
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004650 if (!connection->waitQueue.empty()) {
4651 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4652 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004653 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004654 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004655 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004656 }
4657 }
4658 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004659 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004660 }
4661
4662 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004663 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4664 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004665 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004666 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004667 }
4668
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004669 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004670 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4671 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4672 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004673}
4674
Michael Wright3dd60e22019-03-27 22:06:44 +00004675void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4676 const size_t numMonitors = monitors.size();
4677 for (size_t i = 0; i < numMonitors; i++) {
4678 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004679 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004680 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4681 dump += "\n";
4682 }
4683}
4684
Garfield Tan15601662020-09-22 15:32:38 -07004685base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4686 const std::string& name) {
4687#if DEBUG_CHANNEL_CREATION
4688 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004689#endif
4690
Garfield Tan15601662020-09-22 15:32:38 -07004691 std::shared_ptr<InputChannel> serverChannel;
4692 std::unique_ptr<InputChannel> clientChannel;
4693 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4694
4695 if (result) {
4696 return base::Error(result) << "Failed to open input channel pair with name " << name;
4697 }
4698
Michael Wrightd02c5b62014-02-10 15:10:22 -08004699 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004700 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004701 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004702
Garfield Tan15601662020-09-22 15:32:38 -07004703 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004704 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004705 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004706
Michael Wrightd02c5b62014-02-10 15:10:22 -08004707 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4708 } // release lock
4709
4710 // Wake the looper because some connections have changed.
4711 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004712 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004713}
4714
Garfield Tan15601662020-09-22 15:32:38 -07004715base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
4716 int32_t displayId, bool isGestureMonitor, const std::string& name) {
4717 std::shared_ptr<InputChannel> serverChannel;
4718 std::unique_ptr<InputChannel> clientChannel;
4719 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4720 if (result) {
4721 return base::Error(result) << "Failed to open input channel pair with name " << name;
4722 }
4723
Michael Wright3dd60e22019-03-27 22:06:44 +00004724 { // acquire lock
4725 std::scoped_lock _l(mLock);
4726
4727 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004728 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4729 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004730 }
4731
Garfield Tan15601662020-09-22 15:32:38 -07004732 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004733
Garfield Tan15601662020-09-22 15:32:38 -07004734 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004735 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004736 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004737
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004738 auto& monitorsByDisplay =
4739 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Garfield Tan15601662020-09-22 15:32:38 -07004740 monitorsByDisplay[displayId].emplace_back(serverChannel);
Michael Wright3dd60e22019-03-27 22:06:44 +00004741
4742 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004743 }
Garfield Tan15601662020-09-22 15:32:38 -07004744
Michael Wright3dd60e22019-03-27 22:06:44 +00004745 // Wake the looper because some connections have changed.
4746 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004747 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004748}
4749
Garfield Tan15601662020-09-22 15:32:38 -07004750status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004751 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004752 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004753
Garfield Tan15601662020-09-22 15:32:38 -07004754 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004755 if (status) {
4756 return status;
4757 }
4758 } // release lock
4759
4760 // Wake the poll loop because removing the connection may have changed the current
4761 // synchronization state.
4762 mLooper->wake();
4763 return OK;
4764}
4765
Garfield Tan15601662020-09-22 15:32:38 -07004766status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
4767 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004768 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004769 if (connection == nullptr) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004770 ALOGW("Attempted to unregister already unregistered input channel");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004771 return BAD_VALUE;
4772 }
4773
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004774 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004775 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07004776
Michael Wrightd02c5b62014-02-10 15:10:22 -08004777 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004778 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004779 }
4780
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004781 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004782
4783 nsecs_t currentTime = now();
4784 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4785
4786 connection->status = Connection::STATUS_ZOMBIE;
4787 return OK;
4788}
4789
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004790void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
4791 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
4792 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00004793}
4794
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004795void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004796 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00004797 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004798 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004799 std::vector<Monitor>& monitors = it->second;
4800 const size_t numMonitors = monitors.size();
4801 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004802 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004803 monitors.erase(monitors.begin() + i);
4804 break;
4805 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004806 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004807 if (monitors.empty()) {
4808 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004809 } else {
4810 ++it;
4811 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004812 }
4813}
4814
Michael Wright3dd60e22019-03-27 22:06:44 +00004815status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4816 { // acquire lock
4817 std::scoped_lock _l(mLock);
4818 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4819
4820 if (!foundDisplayId) {
4821 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4822 return BAD_VALUE;
4823 }
4824 int32_t displayId = foundDisplayId.value();
4825
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004826 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4827 mTouchStatesByDisplay.find(displayId);
4828 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004829 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4830 return BAD_VALUE;
4831 }
4832
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004833 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00004834 std::optional<int32_t> foundDeviceId;
4835 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004836 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004837 foundDeviceId = state.deviceId;
4838 }
4839 }
4840 if (!foundDeviceId || !state.down) {
4841 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004842 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004843 return BAD_VALUE;
4844 }
4845 int32_t deviceId = foundDeviceId.value();
4846
4847 // Send cancel events to all the input channels we're stealing from.
4848 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004849 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004850 options.deviceId = deviceId;
4851 options.displayId = displayId;
4852 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004853 std::shared_ptr<InputChannel> channel =
4854 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004855 if (channel != nullptr) {
4856 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4857 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004858 }
4859 // Then clear the current touch state so we stop dispatching to them as well.
4860 state.filterNonMonitors();
4861 }
4862 return OK;
4863}
4864
Michael Wright3dd60e22019-03-27 22:06:44 +00004865std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4866 const sp<IBinder>& token) {
4867 for (const auto& it : mGestureMonitorsByDisplay) {
4868 const std::vector<Monitor>& monitors = it.second;
4869 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004870 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004871 return it.first;
4872 }
4873 }
4874 }
4875 return std::nullopt;
4876}
4877
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004878sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004879 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004880 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004881 }
4882
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004883 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004884 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004885 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004886 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004887 }
4888 }
Robert Carr4e670e52018-08-15 13:26:12 -07004889
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004890 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004891}
4892
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004893std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
4894 sp<Connection> connection = getConnectionLocked(connectionToken);
4895 if (connection == nullptr) {
4896 return "<nullptr>";
4897 }
4898 return connection->getInputChannelName();
4899}
4900
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004901void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004902 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004903 removeByValue(mConnectionsByFd, connection);
4904}
4905
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004906void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4907 const sp<Connection>& connection, uint32_t seq,
4908 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004909 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4910 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004911 commandEntry->connection = connection;
4912 commandEntry->eventTime = currentTime;
4913 commandEntry->seq = seq;
4914 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004915 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004916}
4917
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004918void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4919 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004920 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004921 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004922
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004923 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4924 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004926 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004927}
4928
Vishnu Nairad321cd2020-08-20 16:40:21 -07004929void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
4930 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004931 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4932 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004933 commandEntry->oldToken = oldToken;
4934 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004935 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004936}
4937
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004938void InputDispatcher::onAnrLocked(const Connection& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004939 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
4940 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004941 if (connection.waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004942 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004943 connection.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004944 return;
4945 }
4946 /**
4947 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
4948 * may not be the one that caused the timeout to occur. One possibility is that window timeout
4949 * has changed. This could cause newer entries to time out before the already dispatched
4950 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
4951 * processes the events linearly. So providing information about the oldest entry seems to be
4952 * most useful.
4953 */
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004954 DispatchEntry* oldestEntry = *connection.waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004955 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
4956 std::string reason =
4957 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004958 connection.inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004959 ns2ms(currentWait),
4960 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06004961 sp<IBinder> connectionToken = connection.inputChannel->getConnectionToken();
4962 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004963
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05004964 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4965 &InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible);
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06004966 commandEntry->connectionToken = connectionToken;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004967 commandEntry->reason = std::move(reason);
4968 postCommandLocked(std::move(commandEntry));
4969}
4970
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05004971void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
4972 std::string reason =
4973 StringPrintf("%s does not have a focused window", application->getName().c_str());
4974 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004975
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05004976 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4977 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
4978 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004979 postCommandLocked(std::move(commandEntry));
4980}
4981
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00004982void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
4983 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4984 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
4985 commandEntry->obscuringPackage = obscuringPackage;
4986 postCommandLocked(std::move(commandEntry));
4987}
4988
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004989void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
4990 const std::string& reason) {
4991 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
4992 updateLastAnrStateLocked(windowLabel, reason);
4993}
4994
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05004995void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
4996 const std::string& reason) {
4997 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004998 updateLastAnrStateLocked(windowLabel, reason);
4999}
5000
5001void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5002 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005003 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005004 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005005 struct tm tm;
5006 localtime_r(&t, &tm);
5007 char timestr[64];
5008 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005009 mLastAnrState.clear();
5010 mLastAnrState += INDENT "ANR:\n";
5011 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005012 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5013 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005014 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005015}
5016
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005017void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005018 mLock.unlock();
5019
5020 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5021
5022 mLock.lock();
5023}
5024
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005025void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005026 sp<Connection> connection = commandEntry->connection;
5027
5028 if (connection->status != Connection::STATUS_ZOMBIE) {
5029 mLock.unlock();
5030
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005031 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005032
5033 mLock.lock();
5034 }
5035}
5036
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005037void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005038 sp<IBinder> oldToken = commandEntry->oldToken;
5039 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005040 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005041 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005042 mLock.lock();
5043}
5044
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005045void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005046 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005047
5048 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5049
5050 mLock.lock();
5051}
5052
5053void InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible(
5054 CommandEntry* commandEntry) {
5055 mLock.unlock();
5056
5057 mPolicy->notifyConnectionUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005058
5059 mLock.lock();
5060
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005061 // stop waking up for events in this connection, it is already not responding
5062 sp<Connection> connection = getConnectionLocked(commandEntry->connectionToken);
5063 if (connection == nullptr) {
5064 return;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005065 }
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005066 cancelEventsForAnrLocked(connection);
5067}
5068
5069void InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5070 mLock.unlock();
5071
5072 mPolicy->notifyConnectionResponsive(commandEntry->connectionToken);
5073
5074 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005075}
5076
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005077void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5078 mLock.unlock();
5079
5080 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5081
5082 mLock.lock();
5083}
5084
Michael Wrightd02c5b62014-02-10 15:10:22 -08005085void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5086 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005087 KeyEntry& entry = *(commandEntry->keyEntry);
5088 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005089
5090 mLock.unlock();
5091
Michael Wright2b3c3302018-03-02 17:19:13 +00005092 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005093 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005094 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005095 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5096 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005097 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005098 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005099
5100 mLock.lock();
5101
5102 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005103 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005104 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005105 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005106 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005107 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5108 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005109 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005110}
5111
chaviwfd6d3512019-03-25 13:23:49 -07005112void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5113 mLock.unlock();
5114 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5115 mLock.lock();
5116}
5117
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005118/**
5119 * Connection is responsive if it has no events in the waitQueue that are older than the
5120 * current time.
5121 */
5122static bool isConnectionResponsive(const Connection& connection) {
5123 const nsecs_t currentTime = now();
5124 for (const DispatchEntry* entry : connection.waitQueue) {
5125 if (entry->timeoutTime < currentTime) {
5126 return false;
5127 }
5128 }
5129 return true;
5130}
5131
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005132void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005133 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005134 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005135 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005136 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005137
5138 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005139 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005140 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005141 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005142 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005143 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005144 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005145 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005146 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5147 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005148 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005149 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005150
5151 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005152 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005153 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005154 restartEvent =
5155 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005156 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005157 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005158 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5159 handled);
5160 } else {
5161 restartEvent = false;
5162 }
5163
5164 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005165 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005166 // contents of the wait queue to have been drained, so we need to double-check
5167 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005168 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5169 if (dispatchEntryIt != connection->waitQueue.end()) {
5170 dispatchEntry = *dispatchEntryIt;
5171 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005172 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5173 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005174 if (!connection->responsive) {
5175 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005176 if (connection->responsive) {
5177 // The connection was unresponsive, and now it's responsive. Tell the policy
5178 // about it so that it can stop ANR.
5179 std::unique_ptr<CommandEntry> connectionResponsiveCommand =
5180 std::make_unique<CommandEntry>(
5181 &InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible);
5182 connectionResponsiveCommand->connectionToken = connectionToken;
5183 postCommandLocked(std::move(connectionResponsiveCommand));
5184 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005185 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005186 traceWaitQueueLength(connection);
5187 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005188 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005189 traceOutboundQueueLength(connection);
5190 } else {
5191 releaseDispatchEntry(dispatchEntry);
5192 }
5193 }
5194
5195 // Start the next dispatch cycle for this connection.
5196 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005197}
5198
5199bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005200 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005201 KeyEntry& keyEntry, bool handled) {
5202 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005203 if (!handled) {
5204 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005205 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005206 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005207 return false;
5208 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005209
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005210 // Get the fallback key state.
5211 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005212 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005213 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005214 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005215 connection->inputState.removeFallbackKey(originalKeyCode);
5216 }
5217
5218 if (handled || !dispatchEntry->hasForegroundTarget()) {
5219 // If the application handles the original key for which we previously
5220 // generated a fallback or if the window is not a foreground window,
5221 // then cancel the associated fallback key, if any.
5222 if (fallbackKeyCode != -1) {
5223 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005224#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005225 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005226 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005227 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005228#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005229 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005230 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005231
5232 mLock.unlock();
5233
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005234 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005235 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005236
5237 mLock.lock();
5238
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005239 // Cancel the fallback key.
5240 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005241 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005242 "application handled the original non-fallback key "
5243 "or is no longer a foreground target, "
5244 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005245 options.keyCode = fallbackKeyCode;
5246 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005247 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005248 connection->inputState.removeFallbackKey(originalKeyCode);
5249 }
5250 } else {
5251 // If the application did not handle a non-fallback key, first check
5252 // that we are in a good state to perform unhandled key event processing
5253 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005254 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005255 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005256#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005257 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005258 "since this is not an initial down. "
5259 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005260 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005261#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005262 return false;
5263 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005264
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005265 // Dispatch the unhandled key to the policy.
5266#if DEBUG_OUTBOUND_EVENT_DETAILS
5267 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005268 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005269 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005270#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005271 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005272
5273 mLock.unlock();
5274
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005275 bool fallback =
5276 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005277 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005278
5279 mLock.lock();
5280
5281 if (connection->status != Connection::STATUS_NORMAL) {
5282 connection->inputState.removeFallbackKey(originalKeyCode);
5283 return false;
5284 }
5285
5286 // Latch the fallback keycode for this key on an initial down.
5287 // The fallback keycode cannot change at any other point in the lifecycle.
5288 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005289 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005290 fallbackKeyCode = event.getKeyCode();
5291 } else {
5292 fallbackKeyCode = AKEYCODE_UNKNOWN;
5293 }
5294 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5295 }
5296
5297 ALOG_ASSERT(fallbackKeyCode != -1);
5298
5299 // Cancel the fallback key if the policy decides not to send it anymore.
5300 // We will continue to dispatch the key to the policy but we will no
5301 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005302 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5303 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005304#if DEBUG_OUTBOUND_EVENT_DETAILS
5305 if (fallback) {
5306 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005307 "as a fallback for %d, but on the DOWN it had requested "
5308 "to send %d instead. Fallback canceled.",
5309 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005310 } else {
5311 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005312 "but on the DOWN it had requested to send %d. "
5313 "Fallback canceled.",
5314 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005315 }
5316#endif
5317
5318 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5319 "canceling fallback, policy no longer desires it");
5320 options.keyCode = fallbackKeyCode;
5321 synthesizeCancelationEventsForConnectionLocked(connection, options);
5322
5323 fallback = false;
5324 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005325 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005326 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005327 }
5328 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005329
5330#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005331 {
5332 std::string msg;
5333 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5334 connection->inputState.getFallbackKeys();
5335 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005336 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005337 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005338 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005339 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005340 }
5341#endif
5342
5343 if (fallback) {
5344 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005345 keyEntry.eventTime = event.getEventTime();
5346 keyEntry.deviceId = event.getDeviceId();
5347 keyEntry.source = event.getSource();
5348 keyEntry.displayId = event.getDisplayId();
5349 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5350 keyEntry.keyCode = fallbackKeyCode;
5351 keyEntry.scanCode = event.getScanCode();
5352 keyEntry.metaState = event.getMetaState();
5353 keyEntry.repeatCount = event.getRepeatCount();
5354 keyEntry.downTime = event.getDownTime();
5355 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005356
5357#if DEBUG_OUTBOUND_EVENT_DETAILS
5358 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005359 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005360 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005361#endif
5362 return true; // restart the event
5363 } else {
5364#if DEBUG_OUTBOUND_EVENT_DETAILS
5365 ALOGD("Unhandled key event: No fallback key.");
5366#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005367
5368 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005369 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005370 }
5371 }
5372 return false;
5373}
5374
5375bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005376 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005377 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005378 return false;
5379}
5380
5381void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5382 mLock.unlock();
5383
5384 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5385
5386 mLock.lock();
5387}
5388
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005389KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
5390 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08005391 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08005392 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
5393 entry.repeatCount, entry.downTime, entry.eventTime);
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005394 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005395}
5396
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005397void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5398 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005399 // TODO Write some statistics about how long we spend waiting.
5400}
5401
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005402/**
5403 * Report the touch event latency to the statsd server.
5404 * Input events are reported for statistics if:
5405 * - This is a touchscreen event
5406 * - InputFilter is not enabled
5407 * - Event is not injected or synthesized
5408 *
5409 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5410 * from getting aggregated with the "old" data.
5411 */
5412void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5413 REQUIRES(mLock) {
5414 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5415 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5416 if (!reportForStatistics) {
5417 return;
5418 }
5419
5420 if (mTouchStatistics.shouldReport()) {
5421 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5422 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5423 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5424 mTouchStatistics.reset();
5425 }
5426 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5427 mTouchStatistics.addValue(latencyMicros);
5428}
5429
Michael Wrightd02c5b62014-02-10 15:10:22 -08005430void InputDispatcher::traceInboundQueueLengthLocked() {
5431 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005432 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005433 }
5434}
5435
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005436void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005437 if (ATRACE_ENABLED()) {
5438 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005439 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005440 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005441 }
5442}
5443
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005444void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005445 if (ATRACE_ENABLED()) {
5446 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005447 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005448 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005449 }
5450}
5451
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005452void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005453 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005454
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005455 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005456 dumpDispatchStateLocked(dump);
5457
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005458 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005459 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005460 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005461 }
5462}
5463
5464void InputDispatcher::monitor() {
5465 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005466 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005467 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005468 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005469}
5470
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005471/**
5472 * Wake up the dispatcher and wait until it processes all events and commands.
5473 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5474 * this method can be safely called from any thread, as long as you've ensured that
5475 * the work you are interested in completing has already been queued.
5476 */
5477bool InputDispatcher::waitForIdle() {
5478 /**
5479 * Timeout should represent the longest possible time that a device might spend processing
5480 * events and commands.
5481 */
5482 constexpr std::chrono::duration TIMEOUT = 100ms;
5483 std::unique_lock lock(mLock);
5484 mLooper->wake();
5485 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5486 return result == std::cv_status::no_timeout;
5487}
5488
Vishnu Naire798b472020-07-23 13:52:21 -07005489/**
5490 * Sets focus to the window identified by the token. This must be called
5491 * after updating any input window handles.
5492 *
5493 * Params:
5494 * request.token - input channel token used to identify the window that should gain focus.
5495 * request.focusedToken - the token that the caller expects currently to be focused. If the
5496 * specified token does not match the currently focused window, this request will be dropped.
5497 * If the specified focused token matches the currently focused window, the call will succeed.
5498 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5499 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5500 * when requesting the focus change. This determines which request gets
5501 * precedence if there is a focus change request from another source such as pointer down.
5502 */
Vishnu Nair958da932020-08-21 17:12:37 -07005503void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5504 { // acquire lock
5505 std::scoped_lock _l(mLock);
5506
5507 const int32_t displayId = request.displayId;
5508 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5509 if (request.focusedToken && oldFocusedToken != request.focusedToken) {
5510 ALOGD_IF(DEBUG_FOCUS,
5511 "setFocusedWindow on display %" PRId32
5512 " ignored, reason: focusedToken is not focused",
5513 displayId);
5514 return;
5515 }
5516
5517 mPendingFocusRequests.erase(displayId);
5518 FocusResult result = handleFocusRequestLocked(request);
5519 if (result == FocusResult::NOT_VISIBLE) {
5520 // The requested window is not currently visible. Wait for the window to become visible
5521 // and then provide it focus. This is to handle situations where a user action triggers
5522 // a new window to appear. We want to be able to queue any key events after the user
5523 // action and deliver it to the newly focused window. In order for this to happen, we
5524 // take focus from the currently focused window so key events can be queued.
5525 ALOGD_IF(DEBUG_FOCUS,
5526 "setFocusedWindow on display %" PRId32
5527 " pending, reason: window is not visible",
5528 displayId);
5529 mPendingFocusRequests[displayId] = request;
5530 onFocusChangedLocked(oldFocusedToken, nullptr, displayId,
5531 "setFocusedWindow_AwaitingWindowVisibility");
5532 } else if (result != FocusResult::OK) {
5533 ALOGW("setFocusedWindow on display %" PRId32 " ignored, reason:%s", displayId,
5534 typeToString(result));
5535 }
5536 } // release lock
5537 // Wake up poll loop since it may need to make new input dispatching choices.
5538 mLooper->wake();
5539}
5540
5541InputDispatcher::FocusResult InputDispatcher::handleFocusRequestLocked(
5542 const FocusRequest& request) {
5543 const int32_t displayId = request.displayId;
5544 const sp<IBinder> newFocusedToken = request.token;
5545 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5546
5547 if (oldFocusedToken == request.token) {
5548 ALOGD_IF(DEBUG_FOCUS,
5549 "setFocusedWindow on display %" PRId32 " ignored, reason: already focused",
5550 displayId);
5551 return FocusResult::OK;
5552 }
5553
5554 FocusResult result = checkTokenFocusableLocked(newFocusedToken, displayId);
5555 if (result != FocusResult::OK) {
5556 return result;
5557 }
5558
5559 std::string_view reason =
5560 (request.focusedToken) ? "setFocusedWindow_FocusCheck" : "setFocusedWindow";
5561 onFocusChangedLocked(oldFocusedToken, newFocusedToken, displayId, reason);
5562 return FocusResult::OK;
5563}
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005564
Vishnu Nairad321cd2020-08-20 16:40:21 -07005565void InputDispatcher::onFocusChangedLocked(const sp<IBinder>& oldFocusedToken,
5566 const sp<IBinder>& newFocusedToken, int32_t displayId,
5567 std::string_view reason) {
5568 if (oldFocusedToken) {
5569 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(oldFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005570 if (focusedInputChannel) {
5571 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5572 "focus left window");
5573 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005574 enqueueFocusEventLocked(oldFocusedToken, false /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005575 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005576 mFocusedWindowTokenByDisplay.erase(displayId);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005577 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005578 if (newFocusedToken) {
5579 mFocusedWindowTokenByDisplay[displayId] = newFocusedToken;
5580 enqueueFocusEventLocked(newFocusedToken, true /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005581 }
5582
5583 if (mFocusedDisplayId == displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005584 notifyFocusChangedLocked(oldFocusedToken, newFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005585 }
5586}
Vishnu Nair958da932020-08-21 17:12:37 -07005587
5588/**
5589 * Checks if the window token can be focused on a display. The token can be focused if there is
5590 * at least one window handle that is visible with the same token and all window handles with the
5591 * same token are focusable.
5592 *
5593 * In the case of mirroring, two windows may share the same window token and their visibility
5594 * might be different. Example, the mirrored window can cover the window its mirroring. However,
5595 * we expect the focusability of the windows to match since its hard to reason why one window can
5596 * receive focus events and the other cannot when both are backed by the same input channel.
5597 */
5598InputDispatcher::FocusResult InputDispatcher::checkTokenFocusableLocked(const sp<IBinder>& token,
5599 int32_t displayId) const {
5600 bool allWindowsAreFocusable = true;
5601 bool visibleWindowFound = false;
5602 bool windowFound = false;
5603 for (const sp<InputWindowHandle>& window : getWindowHandlesLocked(displayId)) {
5604 if (window->getToken() != token) {
5605 continue;
5606 }
5607 windowFound = true;
5608 if (window->getInfo()->visible) {
5609 // Check if at least a single window is visible.
5610 visibleWindowFound = true;
5611 }
5612 if (!window->getInfo()->focusable) {
5613 // Check if all windows with the window token are focusable.
5614 allWindowsAreFocusable = false;
5615 break;
5616 }
5617 }
5618
5619 if (!windowFound) {
5620 return FocusResult::NO_WINDOW;
5621 }
5622 if (!allWindowsAreFocusable) {
5623 return FocusResult::NOT_FOCUSABLE;
5624 }
5625 if (!visibleWindowFound) {
5626 return FocusResult::NOT_VISIBLE;
5627 }
5628
5629 return FocusResult::OK;
5630}
Garfield Tane84e6f92019-08-29 17:28:41 -07005631} // namespace android::inputdispatcher