blob: 0495d68000b46b26c4f6a55f78218e76486e3d25 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
Garfield Tan15601662020-09-22 15:32:38 -070031// Log debug messages about channel creation
32#define DEBUG_CHANNEL_CREATION 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080033
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
Siarhei Vishniakou86587282019-09-09 18:20:15 +010038static constexpr bool DEBUG_FOCUS = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -080039
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +000040// Log debug messages about touch occlusion
41// STOPSHIP(b/169067926): Set to false
42static constexpr bool DEBUG_TOUCH_OCCLUSION = true;
43
Michael Wrightd02c5b62014-02-10 15:10:22 -080044// Log debug messages about the app switch latency optimization.
45#define DEBUG_APP_SWITCH 0
46
47// Log debug messages about hover events.
48#define DEBUG_HOVER 0
49
Michael Wright2b3c3302018-03-02 17:19:13 +000050#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080051#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050052#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070053#include <binder/Binder.h>
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100054#include <binder/IServiceManager.h>
55#include <com/android/internal/compat/IPlatformCompatNative.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080056#include <input/InputDevice.h>
Michael Wright44753b12020-07-08 13:48:11 +010057#include <input/InputWindow.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070058#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000059#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070060#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010061#include <statslog.h>
62#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070063#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080064
Michael Wright44753b12020-07-08 13:48:11 +010065#include <cerrno>
66#include <cinttypes>
67#include <climits>
68#include <cstddef>
69#include <ctime>
70#include <queue>
71#include <sstream>
72
73#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070074#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010075
Michael Wrightd02c5b62014-02-10 15:10:22 -080076#define INDENT " "
77#define INDENT2 " "
78#define INDENT3 " "
79#define INDENT4 " "
80
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080081using android::base::StringPrintf;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080082using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100083using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080084using android::os::InputEventInjectionResult;
85using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100086using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080087
Garfield Tane84e6f92019-08-29 17:28:41 -070088namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080089
90// Default input dispatching timeout if there is no focused application or paused window
91// from which to determine an appropriate dispatching timeout.
Siarhei Vishniakou70622952020-07-30 11:17:23 -050092constexpr std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT =
93 std::chrono::milliseconds(android::os::IInputConstants::DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
Michael Wrightd02c5b62014-02-10 15:10:22 -080094
95// Amount of time to allow for all pending events to be processed when an app switch
96// key is on the way. This is used to preempt input dispatch and drop input events
97// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000098constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080099
100// Amount of time to allow for an event to be dispatched (measured since its eventTime)
101// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000102constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800103
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104// 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 +0000105constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
106
107// Log a warning when an interception call takes longer than this to process.
108constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800109
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700110// Additional key latency in case a connection is still processing some motion events.
111// This will help with the case when a user touched a button that opens a new window,
112// and gives us the chance to dispatch the key to this new window.
113constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
114
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000116constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
117
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000118// Event log tags. See EventLogTags.logtags for reference
119constexpr int LOGTAG_INPUT_INTERACTION = 62000;
120constexpr int LOGTAG_INPUT_FOCUS = 62001;
121
Michael Wrightd02c5b62014-02-10 15:10:22 -0800122static inline nsecs_t now() {
123 return systemTime(SYSTEM_TIME_MONOTONIC);
124}
125
126static inline const char* toString(bool value) {
127 return value ? "true" : "false";
128}
129
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000130static inline const std::string toString(sp<IBinder> binder) {
131 if (binder == nullptr) {
132 return "<null>";
133 }
134 return StringPrintf("%p", binder.get());
135}
136
Michael Wrightd02c5b62014-02-10 15:10:22 -0800137static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700138 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
139 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800140}
141
142static bool isValidKeyAction(int32_t action) {
143 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700144 case AKEY_EVENT_ACTION_DOWN:
145 case AKEY_EVENT_ACTION_UP:
146 return true;
147 default:
148 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800149 }
150}
151
152static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700153 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800154 ALOGE("Key event has invalid action code 0x%x", action);
155 return false;
156 }
157 return true;
158}
159
Michael Wright7b159c92015-05-14 14:48:03 +0100160static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800161 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700162 case AMOTION_EVENT_ACTION_DOWN:
163 case AMOTION_EVENT_ACTION_UP:
164 case AMOTION_EVENT_ACTION_CANCEL:
165 case AMOTION_EVENT_ACTION_MOVE:
166 case AMOTION_EVENT_ACTION_OUTSIDE:
167 case AMOTION_EVENT_ACTION_HOVER_ENTER:
168 case AMOTION_EVENT_ACTION_HOVER_MOVE:
169 case AMOTION_EVENT_ACTION_HOVER_EXIT:
170 case AMOTION_EVENT_ACTION_SCROLL:
171 return true;
172 case AMOTION_EVENT_ACTION_POINTER_DOWN:
173 case AMOTION_EVENT_ACTION_POINTER_UP: {
174 int32_t index = getMotionEventActionPointerIndex(action);
175 return index >= 0 && index < pointerCount;
176 }
177 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
178 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
179 return actionButton != 0;
180 default:
181 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800182 }
183}
184
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500185static int64_t millis(std::chrono::nanoseconds t) {
186 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
187}
188
Michael Wright7b159c92015-05-14 14:48:03 +0100189static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700190 const PointerProperties* pointerProperties) {
191 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800192 ALOGE("Motion event has invalid action code 0x%x", action);
193 return false;
194 }
195 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000196 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700197 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800198 return false;
199 }
200 BitSet32 pointerIdBits;
201 for (size_t i = 0; i < pointerCount; i++) {
202 int32_t id = pointerProperties[i].id;
203 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700204 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
205 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800206 return false;
207 }
208 if (pointerIdBits.hasBit(id)) {
209 ALOGE("Motion event has duplicate pointer id %d", id);
210 return false;
211 }
212 pointerIdBits.markBit(id);
213 }
214 return true;
215}
216
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000217static std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800218 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000219 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800220 }
221
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000222 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800223 bool first = true;
224 Region::const_iterator cur = region.begin();
225 Region::const_iterator const tail = region.end();
226 while (cur != tail) {
227 if (first) {
228 first = false;
229 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800230 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800231 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800232 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800233 cur++;
234 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000235 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800236}
237
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500238static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
239 constexpr size_t maxEntries = 50; // max events to print
240 constexpr size_t skipBegin = maxEntries / 2;
241 const size_t skipEnd = queue.size() - maxEntries / 2;
242 // skip from maxEntries / 2 ... size() - maxEntries/2
243 // only print from 0 .. skipBegin and then from skipEnd .. size()
244
245 std::string dump;
246 for (size_t i = 0; i < queue.size(); i++) {
247 const DispatchEntry& entry = *queue[i];
248 if (i >= skipBegin && i < skipEnd) {
249 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
250 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
251 continue;
252 }
253 dump.append(INDENT4);
254 dump += entry.eventEntry->getDescription();
255 dump += StringPrintf(", seq=%" PRIu32
256 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
257 entry.seq, entry.targetFlags, entry.resolvedAction,
258 ns2ms(currentTime - entry.eventEntry->eventTime));
259 if (entry.deliveryTime != 0) {
260 // This entry was delivered, so add information on how long we've been waiting
261 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
262 }
263 dump.append("\n");
264 }
265 return dump;
266}
267
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700268/**
269 * Find the entry in std::unordered_map by key, and return it.
270 * If the entry is not found, return a default constructed entry.
271 *
272 * Useful when the entries are vectors, since an empty vector will be returned
273 * if the entry is not found.
274 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
275 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700276template <typename K, typename V>
277static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700278 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700279 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800280}
281
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700282/**
283 * Find the entry in std::unordered_map by value, and remove it.
284 * If more than one entry has the same value, then all matching
285 * key-value pairs will be removed.
286 *
287 * Return true if at least one value has been removed.
288 */
289template <typename K, typename V>
290static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
291 bool removed = false;
292 for (auto it = map.begin(); it != map.end();) {
293 if (it->second == value) {
294 it = map.erase(it);
295 removed = true;
296 } else {
297 it++;
298 }
299 }
300 return removed;
301}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800302
chaviwaf87b3e2019-10-01 16:59:28 -0700303static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
304 if (first == second) {
305 return true;
306 }
307
308 if (first == nullptr || second == nullptr) {
309 return false;
310 }
311
312 return first->getToken() == second->getToken();
313}
314
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000315static bool haveSameApplicationToken(const InputWindowInfo* first, const InputWindowInfo* second) {
316 if (first == nullptr || second == nullptr) {
317 return false;
318 }
319 return first->applicationInfo.token != nullptr &&
320 first->applicationInfo.token == second->applicationInfo.token;
321}
322
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800323static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
324 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
325}
326
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000327static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700328 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000329 int32_t inputTargetFlags) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900330 if (eventEntry->type == EventEntry::Type::MOTION) {
331 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
332 if (motionEntry.source & AINPUT_SOURCE_CLASS_JOYSTICK) {
333 const ui::Transform identityTransform;
334 // Use identity transform for joystick events events because they don't depend on
335 // the window info
336 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
337 1.0f /*globalScaleFactor*/);
338 }
339 }
340
chaviw1ff3d1e2020-07-01 15:53:47 -0700341 if (inputTarget.useDefaultPointerTransform()) {
342 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700343 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
chaviw1ff3d1e2020-07-01 15:53:47 -0700344 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000345 }
346
347 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
348 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
349
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700350 std::vector<PointerCoords> pointerCoords;
351 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000352
353 // Use the first pointer information to normalize all other pointers. This could be any pointer
354 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700355 // uses the transform for the normalized pointer.
356 const ui::Transform& firstPointerTransform =
357 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
358 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000359
360 // Iterate through all pointers in the event to normalize against the first.
361 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
362 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
363 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700364 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000365
366 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700367 // First, apply the current pointer's transform to update the coordinates into
368 // window space.
369 pointerCoords[pointerIndex].transform(currTransform);
370 // Next, apply the inverse transform of the normalized coordinates so the
371 // current coordinates are transformed into the normalized coordinate space.
372 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000373 }
374
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700375 std::unique_ptr<MotionEntry> combinedMotionEntry =
376 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
377 motionEntry.deviceId, motionEntry.source,
378 motionEntry.displayId, motionEntry.policyFlags,
379 motionEntry.action, motionEntry.actionButton,
380 motionEntry.flags, motionEntry.metaState,
381 motionEntry.buttonState, motionEntry.classification,
382 motionEntry.edgeFlags, motionEntry.xPrecision,
383 motionEntry.yPrecision, motionEntry.xCursorPosition,
384 motionEntry.yCursorPosition, motionEntry.downTime,
385 motionEntry.pointerCount, motionEntry.pointerProperties,
386 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000387
388 if (motionEntry.injectionState) {
389 combinedMotionEntry->injectionState = motionEntry.injectionState;
390 combinedMotionEntry->injectionState->refCount += 1;
391 }
392
393 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700394 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
395 firstPointerTransform, inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000396 return dispatchEntry;
397}
398
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700399static void addGestureMonitors(const std::vector<Monitor>& monitors,
400 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
401 float yOffset = 0) {
402 if (monitors.empty()) {
403 return;
404 }
405 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
406 for (const Monitor& monitor : monitors) {
407 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
408 }
409}
410
Garfield Tan15601662020-09-22 15:32:38 -0700411static status_t openInputChannelPair(const std::string& name,
412 std::shared_ptr<InputChannel>& serverChannel,
413 std::unique_ptr<InputChannel>& clientChannel) {
414 std::unique_ptr<InputChannel> uniqueServerChannel;
415 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
416
417 serverChannel = std::move(uniqueServerChannel);
418 return result;
419}
420
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500421template <typename T>
422static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
423 if (lhs == nullptr && rhs == nullptr) {
424 return true;
425 }
426 if (lhs == nullptr || rhs == nullptr) {
427 return false;
428 }
429 return *lhs == *rhs;
430}
431
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000432static sp<IPlatformCompatNative> getCompatService() {
433 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
434 if (service == nullptr) {
435 ALOGE("Failed to link to compat service");
436 return nullptr;
437 }
438 return interface_cast<IPlatformCompatNative>(service);
439}
440
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000441static KeyEvent createKeyEvent(const KeyEntry& entry) {
442 KeyEvent event;
443 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
444 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
445 entry.repeatCount, entry.downTime, entry.eventTime);
446 return event;
447}
448
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000449static std::optional<int32_t> findMonitorPidByToken(
450 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
451 const sp<IBinder>& token) {
452 for (const auto& it : monitorsByDisplay) {
453 const std::vector<Monitor>& monitors = it.second;
454 for (const Monitor& monitor : monitors) {
455 if (monitor.inputChannel->getConnectionToken() == token) {
456 return monitor.pid;
457 }
458 }
459 }
460 return std::nullopt;
461}
462
Michael Wrightd02c5b62014-02-10 15:10:22 -0800463// --- InputDispatcher ---
464
Garfield Tan00f511d2019-06-12 16:55:40 -0700465InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
466 : mPolicy(policy),
467 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700468 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800469 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700470 mAppSwitchSawKeyDown(false),
471 mAppSwitchDueTime(LONG_LONG_MAX),
472 mNextUnblockedEvent(nullptr),
473 mDispatchEnabled(false),
474 mDispatchFrozen(false),
475 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800476 // mInTouchMode will be initialized by the WindowManager to the default device config.
477 // To avoid leaking stack in case that call never comes, and for tests,
478 // initialize it here anyways.
479 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100480 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000481 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800482 mFocusedWindowRequestedPointerCapture(false),
483 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000484 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800485 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800486 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800487
Yi Kong9b14ac62018-07-17 13:48:38 -0700488 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800489
490 policy->getDispatcherConfiguration(&mConfig);
491}
492
493InputDispatcher::~InputDispatcher() {
494 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800495 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800496
497 resetKeyRepeatLocked();
498 releasePendingEventLocked();
499 drainInboundQueueLocked();
500 }
501
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700502 while (!mConnectionsByFd.empty()) {
503 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700504 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800505 }
506}
507
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700508status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700509 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700510 return ALREADY_EXISTS;
511 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700512 mThread = std::make_unique<InputThread>(
513 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
514 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700515}
516
517status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700518 if (mThread && mThread->isCallingThread()) {
519 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700520 return INVALID_OPERATION;
521 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700522 mThread.reset();
523 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700524}
525
Michael Wrightd02c5b62014-02-10 15:10:22 -0800526void InputDispatcher::dispatchOnce() {
527 nsecs_t nextWakeupTime = LONG_LONG_MAX;
528 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800529 std::scoped_lock _l(mLock);
530 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800531
532 // Run a dispatch loop if there are no pending commands.
533 // The dispatch loop might enqueue commands to run afterwards.
534 if (!haveCommandsLocked()) {
535 dispatchOnceInnerLocked(&nextWakeupTime);
536 }
537
538 // Run all pending commands if there are any.
539 // If any commands were run then force the next poll to wake up immediately.
540 if (runCommandsLockedInterruptible()) {
541 nextWakeupTime = LONG_LONG_MIN;
542 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800543
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700544 // If we are still waiting for ack on some events,
545 // we might have to wake up earlier to check if an app is anr'ing.
546 const nsecs_t nextAnrCheck = processAnrsLocked();
547 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
548
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800549 // We are about to enter an infinitely long sleep, because we have no commands or
550 // pending or queued events
551 if (nextWakeupTime == LONG_LONG_MAX) {
552 mDispatcherEnteredIdle.notify_all();
553 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800554 } // release lock
555
556 // Wait for callback or timeout or wake. (make sure we round up, not down)
557 nsecs_t currentTime = now();
558 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
559 mLooper->pollOnce(timeoutMillis);
560}
561
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700562/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500563 * Raise ANR if there is no focused window.
564 * Before the ANR is raised, do a final state check:
565 * 1. The currently focused application must be the same one we are waiting for.
566 * 2. Ensure we still don't have a focused window.
567 */
568void InputDispatcher::processNoFocusedWindowAnrLocked() {
569 // Check if the application that we are waiting for is still focused.
570 std::shared_ptr<InputApplicationHandle> focusedApplication =
571 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
572 if (focusedApplication == nullptr ||
573 focusedApplication->getApplicationToken() !=
574 mAwaitedFocusedApplication->getApplicationToken()) {
575 // Unexpected because we should have reset the ANR timer when focused application changed
576 ALOGE("Waited for a focused window, but focused application has already changed to %s",
577 focusedApplication->getName().c_str());
578 return; // The focused application has changed.
579 }
580
581 const sp<InputWindowHandle>& focusedWindowHandle =
582 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
583 if (focusedWindowHandle != nullptr) {
584 return; // We now have a focused window. No need for ANR.
585 }
586 onAnrLocked(mAwaitedFocusedApplication);
587}
588
589/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700590 * Check if any of the connections' wait queues have events that are too old.
591 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
592 * Return the time at which we should wake up next.
593 */
594nsecs_t InputDispatcher::processAnrsLocked() {
595 const nsecs_t currentTime = now();
596 nsecs_t nextAnrCheck = LONG_LONG_MAX;
597 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
598 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
599 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500600 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700601 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500602 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700603 return LONG_LONG_MIN;
604 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500605 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700606 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
607 }
608 }
609
610 // Check if any connection ANRs are due
611 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
612 if (currentTime < nextAnrCheck) { // most likely scenario
613 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
614 }
615
616 // If we reached here, we have an unresponsive connection.
617 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
618 if (connection == nullptr) {
619 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
620 return nextAnrCheck;
621 }
622 connection->responsive = false;
623 // Stop waking up for this unresponsive connection
624 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000625 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700626 return LONG_LONG_MIN;
627}
628
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500629std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700630 sp<InputWindowHandle> window = getWindowHandleLocked(token);
631 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500632 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700633 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500634 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700635}
636
Michael Wrightd02c5b62014-02-10 15:10:22 -0800637void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
638 nsecs_t currentTime = now();
639
Jeff Browndc5992e2014-04-11 01:27:26 -0700640 // Reset the key repeat timer whenever normal dispatch is suspended while the
641 // device is in a non-interactive state. This is to ensure that we abort a key
642 // repeat if the device is just coming out of sleep.
643 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800644 resetKeyRepeatLocked();
645 }
646
647 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
648 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100649 if (DEBUG_FOCUS) {
650 ALOGD("Dispatch frozen. Waiting some more.");
651 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800652 return;
653 }
654
655 // Optimize latency of app switches.
656 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
657 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
658 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
659 if (mAppSwitchDueTime < *nextWakeupTime) {
660 *nextWakeupTime = mAppSwitchDueTime;
661 }
662
663 // Ready to start a new event.
664 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700665 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700666 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800667 if (isAppSwitchDue) {
668 // The inbound queue is empty so the app switch key we were waiting
669 // for will never arrive. Stop waiting for it.
670 resetPendingAppSwitchLocked(false);
671 isAppSwitchDue = false;
672 }
673
674 // Synthesize a key repeat if appropriate.
675 if (mKeyRepeatState.lastKeyEntry) {
676 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
677 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
678 } else {
679 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
680 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
681 }
682 }
683 }
684
685 // Nothing to do if there is no pending event.
686 if (!mPendingEvent) {
687 return;
688 }
689 } else {
690 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700691 mPendingEvent = mInboundQueue.front();
692 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800693 traceInboundQueueLengthLocked();
694 }
695
696 // Poke user activity for this event.
697 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700698 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800699 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800700 }
701
702 // Now we have an event to dispatch.
703 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700704 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800705 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700706 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800707 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700708 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800709 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700710 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800711 }
712
713 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700714 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800715 }
716
717 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700718 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700719 const ConfigurationChangedEntry& typedEntry =
720 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700721 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700722 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700723 break;
724 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800725
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700726 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700727 const DeviceResetEntry& typedEntry =
728 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700729 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700730 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700731 break;
732 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800733
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100734 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700735 std::shared_ptr<FocusEntry> typedEntry =
736 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100737 dispatchFocusLocked(currentTime, typedEntry);
738 done = true;
739 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
740 break;
741 }
742
Prabir Pradhan99987712020-11-10 18:43:05 -0800743 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
744 const auto typedEntry =
745 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
746 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
747 done = true;
748 break;
749 }
750
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700751 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700752 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700753 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700754 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700755 resetPendingAppSwitchLocked(true);
756 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700757 } else if (dropReason == DropReason::NOT_DROPPED) {
758 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700759 }
760 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700761 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700762 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700763 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700764 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
765 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700766 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700767 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700768 break;
769 }
770
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700771 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700772 std::shared_ptr<MotionEntry> motionEntry =
773 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700774 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
775 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800776 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700777 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700778 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700779 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700780 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
781 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700782 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700783 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700784 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800785 }
Chris Yef59a2f42020-10-16 12:55:26 -0700786
787 case EventEntry::Type::SENSOR: {
788 std::shared_ptr<SensorEntry> sensorEntry =
789 std::static_pointer_cast<SensorEntry>(mPendingEvent);
790 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
791 dropReason = DropReason::APP_SWITCH;
792 }
793 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
794 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
795 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
796 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
797 dropReason = DropReason::STALE;
798 }
799 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
800 done = true;
801 break;
802 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800803 }
804
805 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700806 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700807 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800808 }
Michael Wright3a981722015-06-10 15:26:13 +0100809 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800810
811 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700812 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800813 }
814}
815
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700816/**
817 * Return true if the events preceding this incoming motion event should be dropped
818 * Return false otherwise (the default behaviour)
819 */
820bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700821 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700822 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700823
824 // Optimize case where the current application is unresponsive and the user
825 // decides to touch a window in a different application.
826 // If the application takes too long to catch up then we drop all events preceding
827 // the touch into the other window.
828 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700829 int32_t displayId = motionEntry.displayId;
830 int32_t x = static_cast<int32_t>(
831 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
832 int32_t y = static_cast<int32_t>(
833 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
834 sp<InputWindowHandle> touchedWindowHandle =
835 findTouchedWindowAtLocked(displayId, x, y, nullptr);
836 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700837 touchedWindowHandle->getApplicationToken() !=
838 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700839 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700840 ALOGI("Pruning input queue because user touched a different application while waiting "
841 "for %s",
842 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700843 return true;
844 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700845
846 // Alternatively, maybe there's a gesture monitor that could handle this event
847 std::vector<TouchedMonitor> gestureMonitors =
848 findTouchedGestureMonitorsLocked(displayId, {});
849 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
850 sp<Connection> connection =
851 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000852 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700853 // This monitor could take more input. Drop all events preceding this
854 // event, so that gesture monitor could get a chance to receive the stream
855 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
856 "responsive gesture monitor that may handle the event",
857 mAwaitedFocusedApplication->getName().c_str());
858 return true;
859 }
860 }
861 }
862
863 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
864 // yet been processed by some connections, the dispatcher will wait for these motion
865 // events to be processed before dispatching the key event. This is because these motion events
866 // may cause a new window to be launched, which the user might expect to receive focus.
867 // To prevent waiting forever for such events, just send the key to the currently focused window
868 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
869 ALOGD("Received a new pointer down event, stop waiting for events to process and "
870 "just send the pending key event to the focused window.");
871 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700872 }
873 return false;
874}
875
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700876bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700877 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700878 mInboundQueue.push_back(std::move(newEntry));
879 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800880 traceInboundQueueLengthLocked();
881
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700882 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700883 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700884 // Optimize app switch latency.
885 // If the application takes too long to catch up then we drop all events preceding
886 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700887 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700888 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700889 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700890 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700891 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700892 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800893#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700894 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800895#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700896 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700897 mAppSwitchSawKeyDown = false;
898 needWake = true;
899 }
900 }
901 }
902 break;
903 }
904
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700905 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700906 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
907 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700908 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800909 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700910 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800911 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100912 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700913 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
914 break;
915 }
916 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -0800917 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -0700918 case EventEntry::Type::SENSOR:
Prabir Pradhan99987712020-11-10 18:43:05 -0800919 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700920 // nothing to do
921 break;
922 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800923 }
924
925 return needWake;
926}
927
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700928void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -0700929 // Do not store sensor event in recent queue to avoid flooding the queue.
930 if (entry->type != EventEntry::Type::SENSOR) {
931 mRecentQueue.push_back(entry);
932 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700933 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700934 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800935 }
936}
937
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700938sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700939 int32_t y, TouchState* touchState,
940 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700941 bool addPortalWindows) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700942 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
943 LOG_ALWAYS_FATAL(
944 "Must provide a valid touch state if adding portal windows or outside targets");
945 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800946 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700947 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800948 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800949 const InputWindowInfo* windowInfo = windowHandle->getInfo();
950 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100951 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800952
953 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100954 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
955 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
956 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800957 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800958 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700959 if (portalToDisplayId != ADISPLAY_ID_NONE &&
960 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800961 if (addPortalWindows) {
962 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700963 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800964 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700965 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700966 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800967 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800968 // Found window.
969 return windowHandle;
970 }
971 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800972
Michael Wright44753b12020-07-08 13:48:11 +0100973 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700974 touchState->addOrUpdateWindow(windowHandle,
975 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
976 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800977 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800978 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800979 }
980 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700981 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800982}
983
Garfield Tane84e6f92019-08-29 17:28:41 -0700984std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700985 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000986 std::vector<TouchedMonitor> touchedMonitors;
987
988 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
989 addGestureMonitors(monitors, touchedMonitors);
990 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
991 const InputWindowInfo* windowInfo = portalWindow->getInfo();
992 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700993 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
994 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000995 }
996 return touchedMonitors;
997}
998
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700999void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001000 const char* reason;
1001 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001002 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -08001003#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001004 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001005#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001006 reason = "inbound event was dropped because the policy consumed it";
1007 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001008 case DropReason::DISABLED:
1009 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001010 ALOGI("Dropped event because input dispatch is disabled.");
1011 }
1012 reason = "inbound event was dropped because input dispatch is disabled";
1013 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001014 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001015 ALOGI("Dropped event because of pending overdue app switch.");
1016 reason = "inbound event was dropped because of pending overdue app switch";
1017 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001018 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001019 ALOGI("Dropped event because the current application is not responding and the user "
1020 "has started interacting with a different application.");
1021 reason = "inbound event was dropped because the current application is not responding "
1022 "and the user has started interacting with a different application";
1023 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001024 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001025 ALOGI("Dropped event because it is stale.");
1026 reason = "inbound event was dropped because it is stale";
1027 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001028 case DropReason::NO_POINTER_CAPTURE:
1029 ALOGI("Dropped event because there is no window with Pointer Capture.");
1030 reason = "inbound event was dropped because there is no window with Pointer Capture";
1031 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001032 case DropReason::NOT_DROPPED: {
1033 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001034 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001035 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001036 }
1037
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001038 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001039 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001040 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1041 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001042 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001043 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001044 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001045 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1046 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001047 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1048 synthesizeCancelationEventsForAllConnectionsLocked(options);
1049 } else {
1050 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1051 synthesizeCancelationEventsForAllConnectionsLocked(options);
1052 }
1053 break;
1054 }
Chris Yef59a2f42020-10-16 12:55:26 -07001055 case EventEntry::Type::SENSOR: {
1056 break;
1057 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001058 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1059 break;
1060 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001061 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001062 case EventEntry::Type::CONFIGURATION_CHANGED:
1063 case EventEntry::Type::DEVICE_RESET: {
Chris Yef59a2f42020-10-16 12:55:26 -07001064 LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001065 break;
1066 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001067 }
1068}
1069
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001070static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001071 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1072 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001073}
1074
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001075bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1076 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1077 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1078 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001079}
1080
1081bool InputDispatcher::isAppSwitchPendingLocked() {
1082 return mAppSwitchDueTime != LONG_LONG_MAX;
1083}
1084
1085void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1086 mAppSwitchDueTime = LONG_LONG_MAX;
1087
1088#if DEBUG_APP_SWITCH
1089 if (handled) {
1090 ALOGD("App switch has arrived.");
1091 } else {
1092 ALOGD("App switch was abandoned.");
1093 }
1094#endif
1095}
1096
Michael Wrightd02c5b62014-02-10 15:10:22 -08001097bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001098 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001099}
1100
1101bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001102 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001103 return false;
1104 }
1105
1106 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001107 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001108 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001109 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001110 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001111
1112 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001113 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001114 return true;
1115}
1116
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001117void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1118 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001119}
1120
1121void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001122 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001123 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001124 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001125 releaseInboundEventLocked(entry);
1126 }
1127 traceInboundQueueLengthLocked();
1128}
1129
1130void InputDispatcher::releasePendingEventLocked() {
1131 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001132 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001133 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001134 }
1135}
1136
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001137void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001138 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001139 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001140#if DEBUG_DISPATCH_CYCLE
1141 ALOGD("Injected inbound event was dropped.");
1142#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001143 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001144 }
1145 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001146 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001147 }
1148 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001149}
1150
1151void InputDispatcher::resetKeyRepeatLocked() {
1152 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001153 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001154 }
1155}
1156
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001157std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1158 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001159
Michael Wright2e732952014-09-24 13:26:59 -07001160 uint32_t policyFlags = entry->policyFlags &
1161 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001162
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001163 std::shared_ptr<KeyEntry> newEntry =
1164 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1165 entry->source, entry->displayId, policyFlags, entry->action,
1166 entry->flags, entry->keyCode, entry->scanCode,
1167 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001168
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001169 newEntry->syntheticRepeat = true;
1170 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001171 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001172 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001173}
1174
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001175bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001176 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001177#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001178 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001179#endif
1180
1181 // Reset key repeating in case a keyboard device was added or removed or something.
1182 resetKeyRepeatLocked();
1183
1184 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001185 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1186 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001187 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001188 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001189 return true;
1190}
1191
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001192bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1193 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001194#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001195 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1196 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001197#endif
1198
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001199 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001200 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001201 synthesizeCancelationEventsForAllConnectionsLocked(options);
1202 return true;
1203}
1204
Vishnu Nairad321cd2020-08-20 16:40:21 -07001205void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001206 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001207 if (mPendingEvent != nullptr) {
1208 // Move the pending event to the front of the queue. This will give the chance
1209 // for the pending event to get dispatched to the newly focused window
1210 mInboundQueue.push_front(mPendingEvent);
1211 mPendingEvent = nullptr;
1212 }
1213
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001214 std::unique_ptr<FocusEntry> focusEntry =
1215 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1216 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001217
1218 // This event should go to the front of the queue, but behind all other focus events
1219 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001220 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001221 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001222 [](const std::shared_ptr<EventEntry>& event) {
1223 return event->type == EventEntry::Type::FOCUS;
1224 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001225
1226 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001227 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001228}
1229
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001230void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001231 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001232 if (channel == nullptr) {
1233 return; // Window has gone away
1234 }
1235 InputTarget target;
1236 target.inputChannel = channel;
1237 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1238 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001239 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1240 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001241 std::string reason = std::string("reason=").append(entry->reason);
1242 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001243 dispatchEventLocked(currentTime, entry, {target});
1244}
1245
Prabir Pradhan99987712020-11-10 18:43:05 -08001246void InputDispatcher::dispatchPointerCaptureChangedLocked(
1247 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1248 DropReason& dropReason) {
1249 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
1250 if (entry->pointerCaptureEnabled == haveWindowWithPointerCapture) {
1251 LOG_ALWAYS_FATAL_IF(mFocusedWindowRequestedPointerCapture,
1252 "The Pointer Capture state has already been dispatched to the window.");
1253 // Pointer capture was already forcefully disabled because of focus change.
1254 dropReason = DropReason::NOT_DROPPED;
1255 return;
1256 }
1257
1258 // Set drop reason for early returns
1259 dropReason = DropReason::NO_POINTER_CAPTURE;
1260
1261 sp<IBinder> token;
1262 if (entry->pointerCaptureEnabled) {
1263 // Enable Pointer Capture
1264 if (!mFocusedWindowRequestedPointerCapture) {
1265 // This can happen if a window requests capture and immediately releases capture.
1266 ALOGW("No window requested Pointer Capture.");
1267 return;
1268 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08001269 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001270 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1271 mWindowTokenWithPointerCapture = token;
1272 } else {
1273 // Disable Pointer Capture
1274 token = mWindowTokenWithPointerCapture;
1275 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001276 if (mFocusedWindowRequestedPointerCapture) {
1277 mFocusedWindowRequestedPointerCapture = false;
1278 setPointerCaptureLocked(false);
1279 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001280 }
1281
1282 auto channel = getInputChannelLocked(token);
1283 if (channel == nullptr) {
1284 // Window has gone away, clean up Pointer Capture state.
1285 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001286 if (mFocusedWindowRequestedPointerCapture) {
1287 mFocusedWindowRequestedPointerCapture = false;
1288 setPointerCaptureLocked(false);
1289 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001290 return;
1291 }
1292 InputTarget target;
1293 target.inputChannel = channel;
1294 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1295 entry->dispatchInProgress = true;
1296 dispatchEventLocked(currentTime, entry, {target});
1297
1298 dropReason = DropReason::NOT_DROPPED;
1299}
1300
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001301bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001302 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001303 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001304 if (!entry->dispatchInProgress) {
1305 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1306 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1307 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1308 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001309 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001310 // We have seen two identical key downs in a row which indicates that the device
1311 // driver is automatically generating key repeats itself. We take note of the
1312 // repeat here, but we disable our own next key repeat timer since it is clear that
1313 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001314 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1315 // Make sure we don't get key down from a different device. If a different
1316 // device Id has same key pressed down, the new device Id will replace the
1317 // current one to hold the key repeat with repeat count reset.
1318 // In the future when got a KEY_UP on the device id, drop it and do not
1319 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001320 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1321 resetKeyRepeatLocked();
1322 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1323 } else {
1324 // Not a repeat. Save key down state in case we do see a repeat later.
1325 resetKeyRepeatLocked();
1326 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1327 }
1328 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001329 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1330 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001331 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001332#if DEBUG_INBOUND_EVENT_DETAILS
1333 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1334#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001335 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001336 resetKeyRepeatLocked();
1337 }
1338
1339 if (entry->repeatCount == 1) {
1340 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1341 } else {
1342 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1343 }
1344
1345 entry->dispatchInProgress = true;
1346
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001347 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001348 }
1349
1350 // Handle case where the policy asked us to try again later last time.
1351 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1352 if (currentTime < entry->interceptKeyWakeupTime) {
1353 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1354 *nextWakeupTime = entry->interceptKeyWakeupTime;
1355 }
1356 return false; // wait until next wakeup
1357 }
1358 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1359 entry->interceptKeyWakeupTime = 0;
1360 }
1361
1362 // Give the policy a chance to intercept the key.
1363 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1364 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001365 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001366 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001367 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001368 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001369 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001370 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001371 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001372 return false; // wait for the command to run
1373 } else {
1374 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1375 }
1376 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001377 if (*dropReason == DropReason::NOT_DROPPED) {
1378 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001379 }
1380 }
1381
1382 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001383 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001384 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001385 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1386 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001387 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001388 return true;
1389 }
1390
1391 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001392 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001393 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001394 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001395 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001396 return false;
1397 }
1398
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001399 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001400 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001401 return true;
1402 }
1403
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001404 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001405 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001406
1407 // Dispatch the key.
1408 dispatchEventLocked(currentTime, entry, inputTargets);
1409 return true;
1410}
1411
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001412void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001413#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001414 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001415 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1416 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001417 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1418 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1419 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001420#endif
1421}
1422
Chris Yef59a2f42020-10-16 12:55:26 -07001423void InputDispatcher::doNotifySensorLockedInterruptible(CommandEntry* commandEntry) {
1424 mLock.unlock();
1425
1426 const std::shared_ptr<SensorEntry>& entry = commandEntry->sensorEntry;
1427 if (entry->accuracyChanged) {
1428 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1429 }
1430 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1431 entry->hwTimestamp, entry->values);
1432 mLock.lock();
1433}
1434
1435void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, std::shared_ptr<SensorEntry> entry,
1436 DropReason* dropReason, nsecs_t* nextWakeupTime) {
1437#if DEBUG_OUTBOUND_EVENT_DETAILS
1438 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1439 "source=0x%x, sensorType=%s",
1440 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
1441 NamedEnum::string(sensorType).c_str());
1442#endif
1443 std::unique_ptr<CommandEntry> commandEntry =
1444 std::make_unique<CommandEntry>(&InputDispatcher::doNotifySensorLockedInterruptible);
1445 commandEntry->sensorEntry = entry;
1446 postCommandLocked(std::move(commandEntry));
1447}
1448
1449bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
1450#if DEBUG_OUTBOUND_EVENT_DETAILS
1451 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
1452 NamedEnum::string(sensorType).c_str());
1453#endif
1454 { // acquire lock
1455 std::scoped_lock _l(mLock);
1456
1457 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1458 std::shared_ptr<EventEntry> entry = *it;
1459 if (entry->type == EventEntry::Type::SENSOR) {
1460 it = mInboundQueue.erase(it);
1461 releaseInboundEventLocked(entry);
1462 }
1463 }
1464 }
1465 return true;
1466}
1467
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001468bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001469 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001470 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001471 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001472 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001473 entry->dispatchInProgress = true;
1474
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001475 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001476 }
1477
1478 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001479 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001480 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001481 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1482 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001483 return true;
1484 }
1485
1486 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1487
1488 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001489 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001490
1491 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001492 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001493 if (isPointerEvent) {
1494 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001495 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001496 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001497 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001498 } else {
1499 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001500 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001501 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001502 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001503 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001504 return false;
1505 }
1506
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001507 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001508 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001509 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1510 return true;
1511 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001512 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001513 CancelationOptions::Mode mode(isPointerEvent
1514 ? CancelationOptions::CANCEL_POINTER_EVENTS
1515 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1516 CancelationOptions options(mode, "input event injection failed");
1517 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001518 return true;
1519 }
1520
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001521 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001522 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001523
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001524 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001525 std::unordered_map<int32_t, TouchState>::iterator it =
1526 mTouchStatesByDisplay.find(entry->displayId);
1527 if (it != mTouchStatesByDisplay.end()) {
1528 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001529 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001530 // The event has gone through these portal windows, so we add monitoring targets of
1531 // the corresponding displays as well.
1532 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001533 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001534 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001535 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001536 }
1537 }
1538 }
1539 }
1540
Michael Wrightd02c5b62014-02-10 15:10:22 -08001541 // Dispatch the motion.
1542 if (conflictingPointerActions) {
1543 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001544 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001545 synthesizeCancelationEventsForAllConnectionsLocked(options);
1546 }
1547 dispatchEventLocked(currentTime, entry, inputTargets);
1548 return true;
1549}
1550
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001551void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001552#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001553 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001554 ", policyFlags=0x%x, "
1555 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1556 "metaState=0x%x, buttonState=0x%x,"
1557 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001558 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1559 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1560 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001561
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001562 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001563 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001564 "x=%f, y=%f, pressure=%f, size=%f, "
1565 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1566 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001567 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1568 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1569 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1570 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1571 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1572 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1573 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1574 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1575 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1576 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001577 }
1578#endif
1579}
1580
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001581void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1582 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001583 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001584 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001585#if DEBUG_DISPATCH_CYCLE
1586 ALOGD("dispatchEventToCurrentInputTargets");
1587#endif
1588
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001589 updateInteractionTokensLocked(*eventEntry, inputTargets);
1590
Michael Wrightd02c5b62014-02-10 15:10:22 -08001591 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1592
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001593 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001594
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001595 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001596 sp<Connection> connection =
1597 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001598 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001599 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001600 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001601 if (DEBUG_FOCUS) {
1602 ALOGD("Dropping event delivery to target with channel '%s' because it "
1603 "is no longer registered with the input dispatcher.",
1604 inputTarget.inputChannel->getName().c_str());
1605 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001606 }
1607 }
1608}
1609
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001610void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1611 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1612 // If the policy decides to close the app, we will get a channel removal event via
1613 // unregisterInputChannel, and will clean up the connection that way. We are already not
1614 // sending new pointers to the connection when it blocked, but focused events will continue to
1615 // pile up.
1616 ALOGW("Canceling events for %s because it is unresponsive",
1617 connection->inputChannel->getName().c_str());
1618 if (connection->status == Connection::STATUS_NORMAL) {
1619 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1620 "application not responding");
1621 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001622 }
1623}
1624
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001625void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001626 if (DEBUG_FOCUS) {
1627 ALOGD("Resetting ANR timeouts.");
1628 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001629
1630 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001631 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001632 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001633}
1634
Tiger Huang721e26f2018-07-24 22:26:19 +08001635/**
1636 * Get the display id that the given event should go to. If this event specifies a valid display id,
1637 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1638 * Focused display is the display that the user most recently interacted with.
1639 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001640int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001641 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001642 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001643 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001644 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1645 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001646 break;
1647 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001648 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001649 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1650 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001651 break;
1652 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001653 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001654 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001655 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001656 case EventEntry::Type::DEVICE_RESET:
1657 case EventEntry::Type::SENSOR: {
1658 ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001659 return ADISPLAY_ID_NONE;
1660 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001661 }
1662 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1663}
1664
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001665bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1666 const char* focusedWindowName) {
1667 if (mAnrTracker.empty()) {
1668 // already processed all events that we waited for
1669 mKeyIsWaitingForEventsTimeout = std::nullopt;
1670 return false;
1671 }
1672
1673 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1674 // Start the timer
1675 ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
1676 "focus to change",
1677 focusedWindowName);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001678 mKeyIsWaitingForEventsTimeout = currentTime +
1679 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1680 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001681 return true;
1682 }
1683
1684 // We still have pending events, and already started the timer
1685 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1686 return true; // Still waiting
1687 }
1688
1689 // Waited too long, and some connection still hasn't processed all motions
1690 // Just send the key to the focused window
1691 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1692 focusedWindowName);
1693 mKeyIsWaitingForEventsTimeout = std::nullopt;
1694 return false;
1695}
1696
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001697InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1698 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1699 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001700 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001701
Tiger Huang721e26f2018-07-24 22:26:19 +08001702 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001703 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001704 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001705 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1706
Michael Wrightd02c5b62014-02-10 15:10:22 -08001707 // If there is no currently focused window and no focused application
1708 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001709 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1710 ALOGI("Dropping %s event because there is no focused window or focused application in "
1711 "display %" PRId32 ".",
Chris Yef59a2f42020-10-16 12:55:26 -07001712 NamedEnum::string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001713 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001714 }
1715
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001716 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1717 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1718 // start interacting with another application via touch (app switch). This code can be removed
1719 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1720 // an app is expected to have a focused window.
1721 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1722 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1723 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001724 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1725 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1726 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001727 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001728 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001729 ALOGW("Waiting because no window has focus but %s may eventually add a "
1730 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001731 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001732 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001733 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001734 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1735 // Already raised ANR. Drop the event
1736 ALOGE("Dropping %s event because there is no focused window",
Chris Yef59a2f42020-10-16 12:55:26 -07001737 NamedEnum::string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001738 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001739 } else {
1740 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001741 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001742 }
1743 }
1744
1745 // we have a valid, non-null focused window
1746 resetNoFocusedWindowTimeoutLocked();
1747
Michael Wrightd02c5b62014-02-10 15:10:22 -08001748 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001749 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001750 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001751 }
1752
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001753 if (focusedWindowHandle->getInfo()->paused) {
1754 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001755 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001756 }
1757
1758 // If the event is a key event, then we must wait for all previous events to
1759 // complete before delivering it because previous events may have the
1760 // side-effect of transferring focus to a different window and we want to
1761 // ensure that the following keys are sent to the new window.
1762 //
1763 // Suppose the user touches a button in a window then immediately presses "A".
1764 // If the button causes a pop-up window to appear then we want to ensure that
1765 // the "A" key is delivered to the new pop-up window. This is because users
1766 // often anticipate pending UI changes when typing on a keyboard.
1767 // To obtain this behavior, we must serialize key events with respect to all
1768 // prior input events.
1769 if (entry.type == EventEntry::Type::KEY) {
1770 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1771 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001772 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001773 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001774 }
1775
1776 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001777 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001778 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1779 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001780
1781 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001782 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001783}
1784
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001785/**
1786 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1787 * that are currently unresponsive.
1788 */
1789std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1790 const std::vector<TouchedMonitor>& monitors) const {
1791 std::vector<TouchedMonitor> responsiveMonitors;
1792 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1793 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1794 sp<Connection> connection = getConnectionLocked(
1795 monitor.monitor.inputChannel->getConnectionToken());
1796 if (connection == nullptr) {
1797 ALOGE("Could not find connection for monitor %s",
1798 monitor.monitor.inputChannel->getName().c_str());
1799 return false;
1800 }
1801 if (!connection->responsive) {
1802 ALOGW("Unresponsive monitor %s will not get the new gesture",
1803 connection->inputChannel->getName().c_str());
1804 return false;
1805 }
1806 return true;
1807 });
1808 return responsiveMonitors;
1809}
1810
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001811InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1812 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1813 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001814 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001815 enum InjectionPermission {
1816 INJECTION_PERMISSION_UNKNOWN,
1817 INJECTION_PERMISSION_GRANTED,
1818 INJECTION_PERMISSION_DENIED
1819 };
1820
Michael Wrightd02c5b62014-02-10 15:10:22 -08001821 // For security reasons, we defer updating the touch state until we are sure that
1822 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001823 int32_t displayId = entry.displayId;
1824 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001825 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1826
1827 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001828 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001829 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001830 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1831 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001832
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001833 // Copy current touch state into tempTouchState.
1834 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1835 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001836 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001837 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001838 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1839 mTouchStatesByDisplay.find(displayId);
1840 if (oldStateIt != mTouchStatesByDisplay.end()) {
1841 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001842 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001843 }
1844
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001845 bool isSplit = tempTouchState.split;
1846 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1847 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1848 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001849 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1850 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1851 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1852 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1853 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001854 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001855 bool wrongDevice = false;
1856 if (newGesture) {
1857 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001858 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001859 ALOGI("Dropping event because a pointer for a different device is already down "
1860 "in display %" PRId32,
1861 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001862 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001863 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001864 switchedDevice = false;
1865 wrongDevice = true;
1866 goto Failed;
1867 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001868 tempTouchState.reset();
1869 tempTouchState.down = down;
1870 tempTouchState.deviceId = entry.deviceId;
1871 tempTouchState.source = entry.source;
1872 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001873 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001874 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001875 ALOGI("Dropping move event because a pointer for a different device is already active "
1876 "in display %" PRId32,
1877 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001878 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001879 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001880 switchedDevice = false;
1881 wrongDevice = true;
1882 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001883 }
1884
1885 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1886 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1887
Garfield Tan00f511d2019-06-12 16:55:40 -07001888 int32_t x;
1889 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001890 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001891 // Always dispatch mouse events to cursor position.
1892 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001893 x = int32_t(entry.xCursorPosition);
1894 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001895 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001896 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1897 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001898 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001899 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001900 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001901 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1902 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001903
1904 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001905 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001906 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001907
Michael Wrightd02c5b62014-02-10 15:10:22 -08001908 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001909 if (newTouchedWindowHandle != nullptr &&
1910 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001911 // New window supports splitting, but we should never split mouse events.
1912 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001913 } else if (isSplit) {
1914 // New window does not support splitting but we have already split events.
1915 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001916 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001917 }
1918
1919 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001920 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001921 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001922 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001923 }
1924
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001925 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1926 ALOGI("Not sending touch event to %s because it is paused",
1927 newTouchedWindowHandle->getName().c_str());
1928 newTouchedWindowHandle = nullptr;
1929 }
1930
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001931 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001932 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001933 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1934 if (!isResponsive) {
1935 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001936 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1937 newTouchedWindowHandle = nullptr;
1938 }
1939 }
1940
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001941 // Drop events that can't be trusted due to occlusion
1942 if (newTouchedWindowHandle != nullptr &&
1943 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1944 TouchOcclusionInfo occlusionInfo =
1945 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001946 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001947 if (DEBUG_TOUCH_OCCLUSION) {
1948 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1949 for (const auto& log : occlusionInfo.debugInfo) {
1950 ALOGD("%s", log.c_str());
1951 }
1952 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001953 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
1954 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1955 ALOGW("Dropping untrusted touch event due to %s/%d",
1956 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1957 newTouchedWindowHandle = nullptr;
1958 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001959 }
1960 }
1961
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001962 // Also don't send the new touch event to unresponsive gesture monitors
1963 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1964
Michael Wright3dd60e22019-03-27 22:06:44 +00001965 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1966 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001967 "(%d, %d) in display %" PRId32 ".",
1968 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001969 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001970 goto Failed;
1971 }
1972
1973 if (newTouchedWindowHandle != nullptr) {
1974 // Set target flags.
1975 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1976 if (isSplit) {
1977 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001978 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001979 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1980 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1981 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1982 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1983 }
1984
1985 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07001986 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
1987 newHoverWindowHandle = nullptr;
1988 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001989 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00001990 }
1991
1992 // Update the temporary touch state.
1993 BitSet32 pointerIds;
1994 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001995 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001996 pointerIds.markBit(pointerId);
1997 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001998 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001999 }
2000
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002001 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002002 } else {
2003 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2004
2005 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002006 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002007 if (DEBUG_FOCUS) {
2008 ALOGD("Dropping event because the pointer is not down or we previously "
2009 "dropped the pointer down event in display %" PRId32,
2010 displayId);
2011 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002012 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002013 goto Failed;
2014 }
2015
2016 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002017 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002018 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002019 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2020 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002021
2022 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002023 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002024 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002025 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2026 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002027 if (DEBUG_FOCUS) {
2028 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2029 oldTouchedWindowHandle->getName().c_str(),
2030 newTouchedWindowHandle->getName().c_str(), displayId);
2031 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002032 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002033 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2034 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2035 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002036
2037 // Make a slippery entrance into the new window.
2038 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2039 isSplit = true;
2040 }
2041
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002042 int32_t targetFlags =
2043 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002044 if (isSplit) {
2045 targetFlags |= InputTarget::FLAG_SPLIT;
2046 }
2047 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2048 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002049 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2050 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002051 }
2052
2053 BitSet32 pointerIds;
2054 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002055 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002056 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002057 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002058 }
2059 }
2060 }
2061
2062 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002063 // Let the previous window know that the hover sequence is over, unless we already did it
2064 // when dispatching it as is to newTouchedWindowHandle.
2065 if (mLastHoverWindowHandle != nullptr &&
2066 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2067 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002068#if DEBUG_HOVER
2069 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002070 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002071#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002072 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2073 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002074 }
2075
Garfield Tandf26e862020-07-01 20:18:19 -07002076 // Let the new window know that the hover sequence is starting, unless we already did it
2077 // when dispatching it as is to newTouchedWindowHandle.
2078 if (newHoverWindowHandle != nullptr &&
2079 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2080 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002081#if DEBUG_HOVER
2082 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002083 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002084#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002085 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2086 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2087 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002088 }
2089 }
2090
2091 // Check permission to inject into all touched foreground windows and ensure there
2092 // is at least one touched foreground window.
2093 {
2094 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002095 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002096 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2097 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002098 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002099 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002100 injectionPermission = INJECTION_PERMISSION_DENIED;
2101 goto Failed;
2102 }
2103 }
2104 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002105 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002106 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002107 ALOGI("Dropping event because there is no touched foreground window in display "
2108 "%" PRId32 " or gesture monitor to receive it.",
2109 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002110 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002111 goto Failed;
2112 }
2113
2114 // Permission granted to injection into all touched foreground windows.
2115 injectionPermission = INJECTION_PERMISSION_GRANTED;
2116 }
2117
2118 // Check whether windows listening for outside touches are owned by the same UID. If it is
2119 // set the policy flag that we will not reveal coordinate information to this window.
2120 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2121 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002122 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002123 if (foregroundWindowHandle) {
2124 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002125 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002126 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2127 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
2128 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002129 tempTouchState.addOrUpdateWindow(inputWindowHandle,
2130 InputTarget::FLAG_ZERO_COORDS,
2131 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002132 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002133 }
2134 }
2135 }
2136 }
2137
Michael Wrightd02c5b62014-02-10 15:10:22 -08002138 // If this is the first pointer going down and the touched window has a wallpaper
2139 // then also add the touched wallpaper windows so they are locked in for the duration
2140 // of the touch gesture.
2141 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2142 // engine only supports touch events. We would need to add a mechanism similar
2143 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2144 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2145 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002146 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002147 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07002148 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002149 getWindowHandlesLocked(displayId);
2150 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002151 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002152 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01002153 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002154 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002155 .addOrUpdateWindow(windowHandle,
2156 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2157 InputTarget::
2158 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2159 InputTarget::FLAG_DISPATCH_AS_IS,
2160 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002161 }
2162 }
2163 }
2164 }
2165
2166 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002167 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002168
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002169 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002170 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002171 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002172 }
2173
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002174 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002175 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002176 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002177 }
2178
Michael Wrightd02c5b62014-02-10 15:10:22 -08002179 // Drop the outside or hover touch windows since we will not care about them
2180 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002181 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002182
2183Failed:
2184 // Check injection permission once and for all.
2185 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002186 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002187 injectionPermission = INJECTION_PERMISSION_GRANTED;
2188 } else {
2189 injectionPermission = INJECTION_PERMISSION_DENIED;
2190 }
2191 }
2192
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002193 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2194 return injectionResult;
2195 }
2196
Michael Wrightd02c5b62014-02-10 15:10:22 -08002197 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002198 if (!wrongDevice) {
2199 if (switchedDevice) {
2200 if (DEBUG_FOCUS) {
2201 ALOGD("Conflicting pointer actions: Switched to a different device.");
2202 }
2203 *outConflictingPointerActions = true;
2204 }
2205
2206 if (isHoverAction) {
2207 // Started hovering, therefore no longer down.
2208 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002209 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002210 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2211 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002212 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002213 *outConflictingPointerActions = true;
2214 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002215 tempTouchState.reset();
2216 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2217 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2218 tempTouchState.deviceId = entry.deviceId;
2219 tempTouchState.source = entry.source;
2220 tempTouchState.displayId = displayId;
2221 }
2222 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2223 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2224 // All pointers up or canceled.
2225 tempTouchState.reset();
2226 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2227 // First pointer went down.
2228 if (oldState && oldState->down) {
2229 if (DEBUG_FOCUS) {
2230 ALOGD("Conflicting pointer actions: Down received while already down.");
2231 }
2232 *outConflictingPointerActions = true;
2233 }
2234 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2235 // One pointer went up.
2236 if (isSplit) {
2237 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2238 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002239
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002240 for (size_t i = 0; i < tempTouchState.windows.size();) {
2241 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2242 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2243 touchedWindow.pointerIds.clearBit(pointerId);
2244 if (touchedWindow.pointerIds.isEmpty()) {
2245 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2246 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002247 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002248 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002249 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002250 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002251 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002252 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002253
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002254 // Save changes unless the action was scroll in which case the temporary touch
2255 // state was only valid for this one action.
2256 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2257 if (tempTouchState.displayId >= 0) {
2258 mTouchStatesByDisplay[displayId] = tempTouchState;
2259 } else {
2260 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002261 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002262 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002263
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002264 // Update hover state.
2265 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002266 }
2267
Michael Wrightd02c5b62014-02-10 15:10:22 -08002268 return injectionResult;
2269}
2270
2271void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002272 int32_t targetFlags, BitSet32 pointerIds,
2273 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002274 std::vector<InputTarget>::iterator it =
2275 std::find_if(inputTargets.begin(), inputTargets.end(),
2276 [&windowHandle](const InputTarget& inputTarget) {
2277 return inputTarget.inputChannel->getConnectionToken() ==
2278 windowHandle->getToken();
2279 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002280
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002281 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002282
2283 if (it == inputTargets.end()) {
2284 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002285 std::shared_ptr<InputChannel> inputChannel =
2286 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002287 if (inputChannel == nullptr) {
2288 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2289 return;
2290 }
2291 inputTarget.inputChannel = inputChannel;
2292 inputTarget.flags = targetFlags;
2293 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2294 inputTargets.push_back(inputTarget);
2295 it = inputTargets.end() - 1;
2296 }
2297
2298 ALOG_ASSERT(it->flags == targetFlags);
2299 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2300
chaviw1ff3d1e2020-07-01 15:53:47 -07002301 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002302}
2303
Michael Wright3dd60e22019-03-27 22:06:44 +00002304void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002305 int32_t displayId, float xOffset,
2306 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002307 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2308 mGlobalMonitorsByDisplay.find(displayId);
2309
2310 if (it != mGlobalMonitorsByDisplay.end()) {
2311 const std::vector<Monitor>& monitors = it->second;
2312 for (const Monitor& monitor : monitors) {
2313 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002314 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002315 }
2316}
2317
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002318void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2319 float yOffset,
2320 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002321 InputTarget target;
2322 target.inputChannel = monitor.inputChannel;
2323 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002324 ui::Transform t;
2325 t.set(xOffset, yOffset);
2326 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002327 inputTargets.push_back(target);
2328}
2329
Michael Wrightd02c5b62014-02-10 15:10:22 -08002330bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002331 const InjectionState* injectionState) {
2332 if (injectionState &&
2333 (windowHandle == nullptr ||
2334 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2335 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002336 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002337 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002338 "owned by uid %d",
2339 injectionState->injectorPid, injectionState->injectorUid,
2340 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002341 } else {
2342 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002343 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002344 }
2345 return false;
2346 }
2347 return true;
2348}
2349
Robert Carrc9bf1d32020-04-13 17:21:08 -07002350/**
2351 * Indicate whether one window handle should be considered as obscuring
2352 * another window handle. We only check a few preconditions. Actually
2353 * checking the bounds is left to the caller.
2354 */
2355static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2356 const sp<InputWindowHandle>& otherHandle) {
2357 // Compare by token so cloned layers aren't counted
2358 if (haveSameToken(windowHandle, otherHandle)) {
2359 return false;
2360 }
2361 auto info = windowHandle->getInfo();
2362 auto otherInfo = otherHandle->getInfo();
2363 if (!otherInfo->visible) {
2364 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002365 } else if (otherInfo->alpha == 0 &&
2366 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2367 // Those act as if they were invisible, so we don't need to flag them.
2368 // We do want to potentially flag touchable windows even if they have 0
2369 // opacity, since they can consume touches and alter the effects of the
2370 // user interaction (eg. apps that rely on
2371 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2372 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2373 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002374 } else if (info->ownerUid == otherInfo->ownerUid) {
2375 // If ownerUid is the same we don't generate occlusion events as there
2376 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002377 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002378 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002379 return false;
2380 } else if (otherInfo->displayId != info->displayId) {
2381 return false;
2382 }
2383 return true;
2384}
2385
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002386/**
2387 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2388 * untrusted, one should check:
2389 *
2390 * 1. If result.hasBlockingOcclusion is true.
2391 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2392 * BLOCK_UNTRUSTED.
2393 *
2394 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2395 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2396 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2397 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2398 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2399 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2400 *
2401 * If neither of those is true, then it means the touch can be allowed.
2402 */
2403InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2404 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002405 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2406 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002407 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2408 TouchOcclusionInfo info;
2409 info.hasBlockingOcclusion = false;
2410 info.obscuringOpacity = 0;
2411 info.obscuringUid = -1;
2412 std::map<int32_t, float> opacityByUid;
2413 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2414 if (windowHandle == otherHandle) {
2415 break; // All future windows are below us. Exit early.
2416 }
2417 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002418 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2419 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002420 if (DEBUG_TOUCH_OCCLUSION) {
2421 info.debugInfo.push_back(
2422 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2423 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002424 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2425 // we perform the checks below to see if the touch can be propagated or not based on the
2426 // window's touch occlusion mode
2427 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2428 info.hasBlockingOcclusion = true;
2429 info.obscuringUid = otherInfo->ownerUid;
2430 info.obscuringPackage = otherInfo->packageName;
2431 break;
2432 }
2433 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2434 uint32_t uid = otherInfo->ownerUid;
2435 float opacity =
2436 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2437 // Given windows A and B:
2438 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2439 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2440 opacityByUid[uid] = opacity;
2441 if (opacity > info.obscuringOpacity) {
2442 info.obscuringOpacity = opacity;
2443 info.obscuringUid = uid;
2444 info.obscuringPackage = otherInfo->packageName;
2445 }
2446 }
2447 }
2448 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002449 if (DEBUG_TOUCH_OCCLUSION) {
2450 info.debugInfo.push_back(
2451 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2452 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002453 return info;
2454}
2455
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002456std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2457 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002458 return StringPrintf(INDENT2
2459 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2460 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2461 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2462 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002463 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002464 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002465 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002466 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2467 info->frameTop, info->frameRight, info->frameBottom,
2468 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002469 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2470 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2471 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002472}
2473
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002474bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2475 if (occlusionInfo.hasBlockingOcclusion) {
2476 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2477 occlusionInfo.obscuringUid);
2478 return false;
2479 }
2480 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2481 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2482 "%.2f, maximum allowed = %.2f)",
2483 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2484 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2485 return false;
2486 }
2487 return true;
2488}
2489
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002490bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2491 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002492 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002493 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002494 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002495 if (windowHandle == otherHandle) {
2496 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002497 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002498 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002499 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002500 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002501 return true;
2502 }
2503 }
2504 return false;
2505}
2506
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002507bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2508 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002509 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002510 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002511 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002512 if (windowHandle == otherHandle) {
2513 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002514 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002515 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002516 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002517 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002518 return true;
2519 }
2520 }
2521 return false;
2522}
2523
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002524std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002525 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002526 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002527 if (applicationHandle != nullptr) {
2528 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002529 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002530 } else {
2531 return applicationHandle->getName();
2532 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002533 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002534 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002535 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002536 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002537 }
2538}
2539
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002540void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002541 if (eventEntry.type == EventEntry::Type::FOCUS ||
2542 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED) {
2543 // Focus or pointer capture changed events are passed to apps, but do not represent user
2544 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002545 return;
2546 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002547 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002548 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002549 if (focusedWindowHandle != nullptr) {
2550 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002551 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002552#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002553 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002554#endif
2555 return;
2556 }
2557 }
2558
2559 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002560 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002561 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002562 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2563 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002564 return;
2565 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002566
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002567 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002568 eventType = USER_ACTIVITY_EVENT_TOUCH;
2569 }
2570 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002571 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002572 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002573 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2574 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002575 return;
2576 }
2577 eventType = USER_ACTIVITY_EVENT_BUTTON;
2578 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002579 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002580 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002581 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002582 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002583 case EventEntry::Type::SENSOR:
Prabir Pradhan99987712020-11-10 18:43:05 -08002584 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002585 LOG_ALWAYS_FATAL("%s events are not user activity",
Chris Yef59a2f42020-10-16 12:55:26 -07002586 NamedEnum::string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002587 break;
2588 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002589 }
2590
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002591 std::unique_ptr<CommandEntry> commandEntry =
2592 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002593 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002594 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002595 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002596}
2597
2598void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002599 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002600 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002601 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002602 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002603 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002604 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002605 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002606 ATRACE_NAME(message.c_str());
2607 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002608#if DEBUG_DISPATCH_CYCLE
2609 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002610 "globalScaleFactor=%f, pointerIds=0x%x %s",
2611 connection->getInputChannelName().c_str(), inputTarget.flags,
2612 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2613 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002614#endif
2615
2616 // Skip this event if the connection status is not normal.
2617 // We don't want to enqueue additional outbound events if the connection is broken.
2618 if (connection->status != Connection::STATUS_NORMAL) {
2619#if DEBUG_DISPATCH_CYCLE
2620 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002621 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002622#endif
2623 return;
2624 }
2625
2626 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002627 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2628 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2629 "Entry type %s should not have FLAG_SPLIT",
Chris Yef59a2f42020-10-16 12:55:26 -07002630 NamedEnum::string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002631
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002632 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002633 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002634 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002635 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002636 if (!splitMotionEntry) {
2637 return; // split event was dropped
2638 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002639 if (DEBUG_FOCUS) {
2640 ALOGD("channel '%s' ~ Split motion event.",
2641 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002642 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002643 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002644 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2645 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002646 return;
2647 }
2648 }
2649
2650 // Not splitting. Enqueue dispatch entries for the event as is.
2651 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2652}
2653
2654void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002655 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002656 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002657 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002658 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002659 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002660 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002661 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002662 ATRACE_NAME(message.c_str());
2663 }
2664
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002665 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002666
2667 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002668 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002669 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002670 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002671 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002672 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002673 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002674 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002675 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002676 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002677 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002678 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002679 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002680
2681 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002682 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002683 startDispatchCycleLocked(currentTime, connection);
2684 }
2685}
2686
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002687void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002688 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002689 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002690 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002691 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002692 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2693 connection->getInputChannelName().c_str(),
2694 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002695 ATRACE_NAME(message.c_str());
2696 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002697 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002698 if (!(inputTargetFlags & dispatchMode)) {
2699 return;
2700 }
2701 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2702
2703 // This is a new event.
2704 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002705 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002706 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002707
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002708 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2709 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002710 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002711 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002712 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002713 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002714 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002715 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002716 dispatchEntry->resolvedAction = keyEntry.action;
2717 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002718
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002719 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2720 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002721#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002722 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2723 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002724#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002725 return; // skip the inconsistent event
2726 }
2727 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002728 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002729
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002730 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002731 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002732 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2733 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2734 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2735 static_cast<int32_t>(IdGenerator::Source::OTHER);
2736 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002737 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2738 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2739 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2740 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2741 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2742 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2743 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2744 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2745 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2746 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2747 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002748 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002749 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002750 }
2751 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002752 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2753 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002754#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002755 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2756 "event",
2757 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002758#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002759 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2760 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002761
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002762 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002763 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2764 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2765 }
2766 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2767 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2768 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002769
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002770 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2771 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002772#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002773 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2774 "event",
2775 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002776#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002777 return; // skip the inconsistent event
2778 }
2779
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002780 dispatchEntry->resolvedEventId =
2781 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2782 ? mIdGenerator.nextId()
2783 : motionEntry.id;
2784 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2785 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2786 ") to MotionEvent(id=0x%" PRIx32 ").",
2787 motionEntry.id, dispatchEntry->resolvedEventId);
2788 ATRACE_NAME(message.c_str());
2789 }
2790
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002791 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002792 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002793
2794 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002795 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002796 case EventEntry::Type::FOCUS:
2797 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002798 break;
2799 }
Chris Yef59a2f42020-10-16 12:55:26 -07002800 case EventEntry::Type::SENSOR: {
2801 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
2802 break;
2803 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002804 case EventEntry::Type::CONFIGURATION_CHANGED:
2805 case EventEntry::Type::DEVICE_RESET: {
2806 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chris Yef59a2f42020-10-16 12:55:26 -07002807 NamedEnum::string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002808 break;
2809 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002810 }
2811
2812 // Remember that we are waiting for this dispatch to complete.
2813 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002814 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002815 }
2816
2817 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002818 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002819 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002820}
2821
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002822/**
2823 * This function is purely for debugging. It helps us understand where the user interaction
2824 * was taking place. For example, if user is touching launcher, we will see a log that user
2825 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2826 * We will see both launcher and wallpaper in that list.
2827 * Once the interaction with a particular set of connections starts, no new logs will be printed
2828 * until the set of interacted connections changes.
2829 *
2830 * The following items are skipped, to reduce the logspam:
2831 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2832 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2833 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2834 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2835 * Both of those ACTION_UP events would not be logged
2836 * Monitors (both gesture and global): any gesture monitors or global monitors receiving events
2837 * will not be logged. This is omitted to reduce the amount of data printed.
2838 * If you see <none>, it's likely that one of the gesture monitors pilfered the event, and therefore
2839 * gesture monitor is the only connection receiving the remainder of the gesture.
2840 */
2841void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2842 const std::vector<InputTarget>& targets) {
2843 // Skip ACTION_UP events, and all events other than keys and motions
2844 if (entry.type == EventEntry::Type::KEY) {
2845 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2846 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2847 return;
2848 }
2849 } else if (entry.type == EventEntry::Type::MOTION) {
2850 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2851 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2852 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2853 return;
2854 }
2855 } else {
2856 return; // Not a key or a motion
2857 }
2858
2859 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2860 std::vector<sp<Connection>> newConnections;
2861 for (const InputTarget& target : targets) {
2862 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2863 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2864 continue; // Skip windows that receive ACTION_OUTSIDE
2865 }
2866
2867 sp<IBinder> token = target.inputChannel->getConnectionToken();
2868 sp<Connection> connection = getConnectionLocked(token);
2869 if (connection == nullptr || connection->monitor) {
2870 continue; // We only need to keep track of the non-monitor connections.
2871 }
2872 newConnectionTokens.insert(std::move(token));
2873 newConnections.emplace_back(connection);
2874 }
2875 if (newConnectionTokens == mInteractionConnectionTokens) {
2876 return; // no change
2877 }
2878 mInteractionConnectionTokens = newConnectionTokens;
2879
2880 std::string windowList;
2881 for (const sp<Connection>& connection : newConnections) {
2882 windowList += connection->getWindowName() + ", ";
2883 }
2884 std::string message = "Interaction with windows: " + windowList;
2885 if (windowList.empty()) {
2886 message += "<none>";
2887 }
2888 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2889}
2890
chaviwfd6d3512019-03-25 13:23:49 -07002891void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002892 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002893 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002894 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2895 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002896 return;
2897 }
2898
Vishnu Nairc519ff72021-01-21 08:23:08 -08002899 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002900 if (focusedToken == token) {
2901 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002902 return;
2903 }
2904
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002905 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2906 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002907 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002908 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002909}
2910
2911void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002912 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002913 if (ATRACE_ENABLED()) {
2914 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002915 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002916 ATRACE_NAME(message.c_str());
2917 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002918#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002919 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002920#endif
2921
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002922 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2923 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002925 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002926 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002927 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002928
2929 // Publish the event.
2930 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002931 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
2932 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002933 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002934 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2935 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002936
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002937 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002938 status = connection->inputPublisher
2939 .publishKeyEvent(dispatchEntry->seq,
2940 dispatchEntry->resolvedEventId, keyEntry.deviceId,
2941 keyEntry.source, keyEntry.displayId,
2942 std::move(hmac), dispatchEntry->resolvedAction,
2943 dispatchEntry->resolvedFlags, keyEntry.keyCode,
2944 keyEntry.scanCode, keyEntry.metaState,
2945 keyEntry.repeatCount, keyEntry.downTime,
2946 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002947 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002948 }
2949
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002950 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002951 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002952
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002953 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002954 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002955
chaviw82357092020-01-28 13:13:06 -08002956 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002957 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002958 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2959 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002960 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002961 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
2962 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002963 // Don't apply window scale here since we don't want scale to affect raw
2964 // coordinates. The scale will be sent back to the client and applied
2965 // later when requesting relative coordinates.
2966 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2967 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002968 }
2969 usingCoords = scaledCoords;
2970 }
2971 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002972 // We don't want the dispatch target to know.
2973 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002974 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002975 scaledCoords[i].clear();
2976 }
2977 usingCoords = scaledCoords;
2978 }
2979 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002980
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002981 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002982
2983 // Publish the motion event.
2984 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002985 .publishMotionEvent(dispatchEntry->seq,
2986 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002987 motionEntry.deviceId, motionEntry.source,
2988 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002989 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002990 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002991 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002992 motionEntry.edgeFlags, motionEntry.metaState,
2993 motionEntry.buttonState,
2994 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07002995 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002996 motionEntry.xPrecision, motionEntry.yPrecision,
2997 motionEntry.xCursorPosition,
2998 motionEntry.yCursorPosition,
2999 motionEntry.downTime, motionEntry.eventTime,
3000 motionEntry.pointerCount,
3001 motionEntry.pointerProperties, usingCoords);
3002 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003003 break;
3004 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003005
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003006 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003007 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003008 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003009 focusEntry.id,
3010 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003011 mInTouchMode);
3012 break;
3013 }
3014
Prabir Pradhan99987712020-11-10 18:43:05 -08003015 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3016 const auto& captureEntry =
3017 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3018 status = connection->inputPublisher
3019 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
3020 captureEntry.pointerCaptureEnabled);
3021 break;
3022 }
3023
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003024 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003025 case EventEntry::Type::DEVICE_RESET:
3026 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003027 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Chris Yef59a2f42020-10-16 12:55:26 -07003028 NamedEnum::string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003029 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003030 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003031 }
3032
3033 // Check the result.
3034 if (status) {
3035 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003036 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003037 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003038 "This is unexpected because the wait queue is empty, so the pipe "
3039 "should be empty and we shouldn't have any problems writing an "
3040 "event to it, status=%d",
3041 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003042 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3043 } else {
3044 // Pipe is full and we are waiting for the app to finish process some events
3045 // before sending more events to it.
3046#if DEBUG_DISPATCH_CYCLE
3047 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003048 "waiting for the application to catch up",
3049 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003050#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003051 }
3052 } else {
3053 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003054 "status=%d",
3055 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003056 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3057 }
3058 return;
3059 }
3060
3061 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003062 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3063 connection->outboundQueue.end(),
3064 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003065 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003066 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003067 if (connection->responsive) {
3068 mAnrTracker.insert(dispatchEntry->timeoutTime,
3069 connection->inputChannel->getConnectionToken());
3070 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003071 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003072 }
3073}
3074
chaviw09c8d2d2020-08-24 15:48:26 -07003075std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3076 size_t size;
3077 switch (event.type) {
3078 case VerifiedInputEvent::Type::KEY: {
3079 size = sizeof(VerifiedKeyEvent);
3080 break;
3081 }
3082 case VerifiedInputEvent::Type::MOTION: {
3083 size = sizeof(VerifiedMotionEvent);
3084 break;
3085 }
3086 }
3087 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3088 return mHmacKeyManager.sign(start, size);
3089}
3090
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003091const std::array<uint8_t, 32> InputDispatcher::getSignature(
3092 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3093 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3094 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3095 // Only sign events up and down events as the purely move events
3096 // are tied to their up/down counterparts so signing would be redundant.
3097 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3098 verifiedEvent.actionMasked = actionMasked;
3099 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003100 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003101 }
3102 return INVALID_HMAC;
3103}
3104
3105const std::array<uint8_t, 32> InputDispatcher::getSignature(
3106 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3107 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3108 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3109 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003110 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003111}
3112
Michael Wrightd02c5b62014-02-10 15:10:22 -08003113void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003114 const sp<Connection>& connection, uint32_t seq,
3115 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003116#if DEBUG_DISPATCH_CYCLE
3117 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003118 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003119#endif
3120
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003121 if (connection->status == Connection::STATUS_BROKEN ||
3122 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003123 return;
3124 }
3125
3126 // Notify other system components and prepare to start the next dispatch cycle.
3127 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
3128}
3129
3130void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003131 const sp<Connection>& connection,
3132 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003133#if DEBUG_DISPATCH_CYCLE
3134 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003135 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003136#endif
3137
3138 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003139 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003140 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003141 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003142 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003143
3144 // The connection appears to be unrecoverably broken.
3145 // Ignore already broken or zombie connections.
3146 if (connection->status == Connection::STATUS_NORMAL) {
3147 connection->status = Connection::STATUS_BROKEN;
3148
3149 if (notify) {
3150 // Notify other system components.
3151 onDispatchCycleBrokenLocked(currentTime, connection);
3152 }
3153 }
3154}
3155
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003156void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3157 while (!queue.empty()) {
3158 DispatchEntry* dispatchEntry = queue.front();
3159 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003160 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003161 }
3162}
3163
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003164void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003165 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003166 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003167 }
3168 delete dispatchEntry;
3169}
3170
3171int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
3172 InputDispatcher* d = static_cast<InputDispatcher*>(data);
3173
3174 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003175 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003176
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003177 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003178 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003179 "fd=%d, events=0x%x",
3180 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003181 return 0; // remove the callback
3182 }
3183
3184 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003185 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003186 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3187 if (!(events & ALOOPER_EVENT_INPUT)) {
3188 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003189 "events=0x%x",
3190 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003191 return 1;
3192 }
3193
3194 nsecs_t currentTime = now();
3195 bool gotOne = false;
3196 status_t status;
3197 for (;;) {
3198 uint32_t seq;
3199 bool handled;
3200 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
3201 if (status) {
3202 break;
3203 }
3204 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
3205 gotOne = true;
3206 }
3207 if (gotOne) {
3208 d->runCommandsLockedInterruptible();
3209 if (status == WOULD_BLOCK) {
3210 return 1;
3211 }
3212 }
3213
3214 notify = status != DEAD_OBJECT || !connection->monitor;
3215 if (notify) {
3216 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003217 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003218 }
3219 } else {
3220 // Monitor channels are never explicitly unregistered.
3221 // We do it automatically when the remote endpoint is closed so don't warn
3222 // about them.
arthurhungd352cb32020-04-28 17:09:28 +08003223 const bool stillHaveWindowHandle =
3224 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3225 nullptr;
3226 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003227 if (notify) {
3228 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003229 "events=0x%x",
3230 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003231 }
3232 }
3233
Garfield Tan15601662020-09-22 15:32:38 -07003234 // Remove the channel.
3235 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003236 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003237 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003238}
3239
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003240void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003241 const CancelationOptions& options) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003242 for (const auto& [fd, connection] : mConnectionsByFd) {
3243 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003244 }
3245}
3246
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003247void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003248 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003249 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3250 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3251}
3252
3253void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3254 const CancelationOptions& options,
3255 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3256 for (const auto& it : monitorsByDisplay) {
3257 const std::vector<Monitor>& monitors = it.second;
3258 for (const Monitor& monitor : monitors) {
3259 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003260 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003261 }
3262}
3263
Michael Wrightd02c5b62014-02-10 15:10:22 -08003264void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003265 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003266 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003267 if (connection == nullptr) {
3268 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003269 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003270
3271 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003272}
3273
3274void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3275 const sp<Connection>& connection, const CancelationOptions& options) {
3276 if (connection->status == Connection::STATUS_BROKEN) {
3277 return;
3278 }
3279
3280 nsecs_t currentTime = now();
3281
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003282 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003283 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003284
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003285 if (cancelationEvents.empty()) {
3286 return;
3287 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003288#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003289 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3290 "with reality: %s, mode=%d.",
3291 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3292 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003293#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003294
3295 InputTarget target;
3296 sp<InputWindowHandle> windowHandle =
3297 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3298 if (windowHandle != nullptr) {
3299 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003300 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003301 target.globalScaleFactor = windowInfo->globalScaleFactor;
3302 }
3303 target.inputChannel = connection->inputChannel;
3304 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3305
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003306 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003307 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003308 switch (cancelationEventEntry->type) {
3309 case EventEntry::Type::KEY: {
3310 logOutboundKeyDetails("cancel - ",
3311 static_cast<const KeyEntry&>(*cancelationEventEntry));
3312 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003313 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003314 case EventEntry::Type::MOTION: {
3315 logOutboundMotionDetails("cancel - ",
3316 static_cast<const MotionEntry&>(*cancelationEventEntry));
3317 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003319 case EventEntry::Type::FOCUS:
3320 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3321 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Chris Yef59a2f42020-10-16 12:55:26 -07003322 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003323 break;
3324 }
3325 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003326 case EventEntry::Type::DEVICE_RESET:
3327 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003328 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003329 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003330 break;
3331 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003332 }
3333
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003334 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3335 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003336 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003337
3338 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003339}
3340
Svet Ganov5d3bc372020-01-26 23:11:07 -08003341void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3342 const sp<Connection>& connection) {
3343 if (connection->status == Connection::STATUS_BROKEN) {
3344 return;
3345 }
3346
3347 nsecs_t currentTime = now();
3348
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003349 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003350 connection->inputState.synthesizePointerDownEvents(currentTime);
3351
3352 if (downEvents.empty()) {
3353 return;
3354 }
3355
3356#if DEBUG_OUTBOUND_EVENT_DETAILS
3357 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3358 connection->getInputChannelName().c_str(), downEvents.size());
3359#endif
3360
3361 InputTarget target;
3362 sp<InputWindowHandle> windowHandle =
3363 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3364 if (windowHandle != nullptr) {
3365 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003366 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003367 target.globalScaleFactor = windowInfo->globalScaleFactor;
3368 }
3369 target.inputChannel = connection->inputChannel;
3370 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3371
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003372 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003373 switch (downEventEntry->type) {
3374 case EventEntry::Type::MOTION: {
3375 logOutboundMotionDetails("down - ",
3376 static_cast<const MotionEntry&>(*downEventEntry));
3377 break;
3378 }
3379
3380 case EventEntry::Type::KEY:
3381 case EventEntry::Type::FOCUS:
3382 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003383 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003384 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3385 case EventEntry::Type::SENSOR: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003386 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003387 NamedEnum::string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003388 break;
3389 }
3390 }
3391
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003392 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3393 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003394 }
3395
3396 startDispatchCycleLocked(currentTime, connection);
3397}
3398
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003399std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3400 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003401 ALOG_ASSERT(pointerIds.value != 0);
3402
3403 uint32_t splitPointerIndexMap[MAX_POINTERS];
3404 PointerProperties splitPointerProperties[MAX_POINTERS];
3405 PointerCoords splitPointerCoords[MAX_POINTERS];
3406
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003407 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003408 uint32_t splitPointerCount = 0;
3409
3410 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003411 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003412 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003413 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003414 uint32_t pointerId = uint32_t(pointerProperties.id);
3415 if (pointerIds.hasBit(pointerId)) {
3416 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3417 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3418 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003419 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003420 splitPointerCount += 1;
3421 }
3422 }
3423
3424 if (splitPointerCount != pointerIds.count()) {
3425 // This is bad. We are missing some of the pointers that we expected to deliver.
3426 // Most likely this indicates that we received an ACTION_MOVE events that has
3427 // different pointer ids than we expected based on the previous ACTION_DOWN
3428 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3429 // in this way.
3430 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003431 "we expected there to be %d pointers. This probably means we received "
3432 "a broken sequence of pointer ids from the input device.",
3433 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003434 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003435 }
3436
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003437 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003438 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003439 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3440 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003441 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3442 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003443 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003444 uint32_t pointerId = uint32_t(pointerProperties.id);
3445 if (pointerIds.hasBit(pointerId)) {
3446 if (pointerIds.count() == 1) {
3447 // The first/last pointer went down/up.
3448 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003449 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003450 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3451 ? AMOTION_EVENT_ACTION_CANCEL
3452 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003453 } else {
3454 // A secondary pointer went down/up.
3455 uint32_t splitPointerIndex = 0;
3456 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3457 splitPointerIndex += 1;
3458 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003459 action = maskedAction |
3460 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003461 }
3462 } else {
3463 // An unrelated pointer changed.
3464 action = AMOTION_EVENT_ACTION_MOVE;
3465 }
3466 }
3467
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003468 int32_t newId = mIdGenerator.nextId();
3469 if (ATRACE_ENABLED()) {
3470 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3471 ") to MotionEvent(id=0x%" PRIx32 ").",
3472 originalMotionEntry.id, newId);
3473 ATRACE_NAME(message.c_str());
3474 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003475 std::unique_ptr<MotionEntry> splitMotionEntry =
3476 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3477 originalMotionEntry.deviceId, originalMotionEntry.source,
3478 originalMotionEntry.displayId,
3479 originalMotionEntry.policyFlags, action,
3480 originalMotionEntry.actionButton,
3481 originalMotionEntry.flags, originalMotionEntry.metaState,
3482 originalMotionEntry.buttonState,
3483 originalMotionEntry.classification,
3484 originalMotionEntry.edgeFlags,
3485 originalMotionEntry.xPrecision,
3486 originalMotionEntry.yPrecision,
3487 originalMotionEntry.xCursorPosition,
3488 originalMotionEntry.yCursorPosition,
3489 originalMotionEntry.downTime, splitPointerCount,
3490 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003491
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003492 if (originalMotionEntry.injectionState) {
3493 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003494 splitMotionEntry->injectionState->refCount += 1;
3495 }
3496
3497 return splitMotionEntry;
3498}
3499
3500void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3501#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003502 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003503#endif
3504
3505 bool needWake;
3506 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003507 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003508
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003509 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3510 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3511 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003512 } // release lock
3513
3514 if (needWake) {
3515 mLooper->wake();
3516 }
3517}
3518
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003519/**
3520 * If one of the meta shortcuts is detected, process them here:
3521 * Meta + Backspace -> generate BACK
3522 * Meta + Enter -> generate HOME
3523 * This will potentially overwrite keyCode and metaState.
3524 */
3525void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003526 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003527 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3528 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3529 if (keyCode == AKEYCODE_DEL) {
3530 newKeyCode = AKEYCODE_BACK;
3531 } else if (keyCode == AKEYCODE_ENTER) {
3532 newKeyCode = AKEYCODE_HOME;
3533 }
3534 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003535 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003536 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003537 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003538 keyCode = newKeyCode;
3539 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3540 }
3541 } else if (action == AKEY_EVENT_ACTION_UP) {
3542 // In order to maintain a consistent stream of up and down events, check to see if the key
3543 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3544 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003545 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003546 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003547 auto replacementIt = mReplacedKeys.find(replacement);
3548 if (replacementIt != mReplacedKeys.end()) {
3549 keyCode = replacementIt->second;
3550 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003551 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3552 }
3553 }
3554}
3555
Michael Wrightd02c5b62014-02-10 15:10:22 -08003556void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3557#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003558 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3559 "policyFlags=0x%x, action=0x%x, "
3560 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3561 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3562 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3563 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003564#endif
3565 if (!validateKeyEvent(args->action)) {
3566 return;
3567 }
3568
3569 uint32_t policyFlags = args->policyFlags;
3570 int32_t flags = args->flags;
3571 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003572 // InputDispatcher tracks and generates key repeats on behalf of
3573 // whatever notifies it, so repeatCount should always be set to 0
3574 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003575 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3576 policyFlags |= POLICY_FLAG_VIRTUAL;
3577 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3578 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003579 if (policyFlags & POLICY_FLAG_FUNCTION) {
3580 metaState |= AMETA_FUNCTION_ON;
3581 }
3582
3583 policyFlags |= POLICY_FLAG_TRUSTED;
3584
Michael Wright78f24442014-08-06 15:55:28 -07003585 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003586 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003587
Michael Wrightd02c5b62014-02-10 15:10:22 -08003588 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003589 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003590 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3591 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003592
Michael Wright2b3c3302018-03-02 17:19:13 +00003593 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003594 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003595 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3596 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003597 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003598 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003599
Michael Wrightd02c5b62014-02-10 15:10:22 -08003600 bool needWake;
3601 { // acquire lock
3602 mLock.lock();
3603
3604 if (shouldSendKeyToInputFilterLocked(args)) {
3605 mLock.unlock();
3606
3607 policyFlags |= POLICY_FLAG_FILTERED;
3608 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3609 return; // event was consumed by the filter
3610 }
3611
3612 mLock.lock();
3613 }
3614
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003615 std::unique_ptr<KeyEntry> newEntry =
3616 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3617 args->displayId, policyFlags, args->action, flags,
3618 keyCode, args->scanCode, metaState, repeatCount,
3619 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003620
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003621 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003622 mLock.unlock();
3623 } // release lock
3624
3625 if (needWake) {
3626 mLooper->wake();
3627 }
3628}
3629
3630bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3631 return mInputFilterEnabled;
3632}
3633
3634void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3635#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003636 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3637 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003638 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3639 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003640 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003641 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3642 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3643 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3644 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003645 for (uint32_t i = 0; i < args->pointerCount; i++) {
3646 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003647 "x=%f, y=%f, pressure=%f, size=%f, "
3648 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3649 "orientation=%f",
3650 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3651 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3652 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3653 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3654 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3655 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3656 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3657 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3658 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3659 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003660 }
3661#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003662 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3663 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003664 return;
3665 }
3666
3667 uint32_t policyFlags = args->policyFlags;
3668 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003669
3670 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003671 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003672 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3673 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003674 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003675 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003676
3677 bool needWake;
3678 { // acquire lock
3679 mLock.lock();
3680
3681 if (shouldSendMotionToInputFilterLocked(args)) {
3682 mLock.unlock();
3683
3684 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003685 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003686 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3687 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003688 args->metaState, args->buttonState, args->classification, transform,
3689 args->xPrecision, args->yPrecision, args->xCursorPosition,
3690 args->yCursorPosition, args->downTime, args->eventTime,
3691 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003692
3693 policyFlags |= POLICY_FLAG_FILTERED;
3694 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3695 return; // event was consumed by the filter
3696 }
3697
3698 mLock.lock();
3699 }
3700
3701 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003702 std::unique_ptr<MotionEntry> newEntry =
3703 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3704 args->source, args->displayId, policyFlags,
3705 args->action, args->actionButton, args->flags,
3706 args->metaState, args->buttonState,
3707 args->classification, args->edgeFlags,
3708 args->xPrecision, args->yPrecision,
3709 args->xCursorPosition, args->yCursorPosition,
3710 args->downTime, args->pointerCount,
3711 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003712
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003713 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003714 mLock.unlock();
3715 } // release lock
3716
3717 if (needWake) {
3718 mLooper->wake();
3719 }
3720}
3721
Chris Yef59a2f42020-10-16 12:55:26 -07003722void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
3723#if DEBUG_INBOUND_EVENT_DETAILS
3724 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3725 " sensorType=%s",
3726 args->id, args->eventTime, args->deviceId, args->source,
3727 NamedEnum::string(args->sensorType).c_str());
3728#endif
3729
3730 bool needWake;
3731 { // acquire lock
3732 mLock.lock();
3733
3734 // Just enqueue a new sensor event.
3735 std::unique_ptr<SensorEntry> newEntry =
3736 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
3737 args->source, 0 /* policyFlags*/, args->hwTimestamp,
3738 args->sensorType, args->accuracy,
3739 args->accuracyChanged, args->values);
3740
3741 needWake = enqueueInboundEventLocked(std::move(newEntry));
3742 mLock.unlock();
3743 } // release lock
3744
3745 if (needWake) {
3746 mLooper->wake();
3747 }
3748}
3749
Michael Wrightd02c5b62014-02-10 15:10:22 -08003750bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003751 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003752}
3753
3754void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3755#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003756 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003757 "switchMask=0x%08x",
3758 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003759#endif
3760
3761 uint32_t policyFlags = args->policyFlags;
3762 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003763 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003764}
3765
3766void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3767#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003768 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3769 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003770#endif
3771
3772 bool needWake;
3773 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003774 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003775
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003776 std::unique_ptr<DeviceResetEntry> newEntry =
3777 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3778 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003779 } // release lock
3780
3781 if (needWake) {
3782 mLooper->wake();
3783 }
3784}
3785
Prabir Pradhan7e186182020-11-10 13:56:45 -08003786void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3787#if DEBUG_INBOUND_EVENT_DETAILS
3788 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3789 args->enabled ? "true" : "false");
3790#endif
3791
Prabir Pradhan99987712020-11-10 18:43:05 -08003792 bool needWake;
3793 { // acquire lock
3794 std::scoped_lock _l(mLock);
3795 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
3796 args->enabled);
3797 needWake = enqueueInboundEventLocked(std::move(entry));
3798 } // release lock
3799
3800 if (needWake) {
3801 mLooper->wake();
3802 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003803}
3804
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003805InputEventInjectionResult InputDispatcher::injectInputEvent(
3806 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3807 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003808#if DEBUG_INBOUND_EVENT_DETAILS
3809 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003810 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3811 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003812#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003813 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003814
3815 policyFlags |= POLICY_FLAG_INJECTED;
3816 if (hasInjectionPermission(injectorPid, injectorUid)) {
3817 policyFlags |= POLICY_FLAG_TRUSTED;
3818 }
3819
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003820 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003821 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003822 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003823 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3824 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003825 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003826 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003827 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003828
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003829 int32_t flags = incomingKey.getFlags();
3830 int32_t keyCode = incomingKey.getKeyCode();
3831 int32_t metaState = incomingKey.getMetaState();
3832 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003833 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003834 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003835 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003836 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3837 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3838 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003839
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003840 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3841 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003842 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003843
3844 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3845 android::base::Timer t;
3846 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3847 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3848 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3849 std::to_string(t.duration().count()).c_str());
3850 }
3851 }
3852
3853 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003854 std::unique_ptr<KeyEntry> injectedEntry =
3855 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3856 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3857 incomingKey.getDisplayId(), policyFlags, action,
3858 flags, keyCode, incomingKey.getScanCode(), metaState,
3859 incomingKey.getRepeatCount(),
3860 incomingKey.getDownTime());
3861 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003862 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003863 }
3864
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003865 case AINPUT_EVENT_TYPE_MOTION: {
3866 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3867 int32_t action = motionEvent->getAction();
3868 size_t pointerCount = motionEvent->getPointerCount();
3869 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3870 int32_t actionButton = motionEvent->getActionButton();
3871 int32_t displayId = motionEvent->getDisplayId();
3872 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003873 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003874 }
3875
3876 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3877 nsecs_t eventTime = motionEvent->getEventTime();
3878 android::base::Timer t;
3879 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3880 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3881 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3882 std::to_string(t.duration().count()).c_str());
3883 }
3884 }
3885
3886 mLock.lock();
3887 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3888 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003889 std::unique_ptr<MotionEntry> injectedEntry =
3890 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3891 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3892 motionEvent->getDisplayId(), policyFlags, action,
3893 actionButton, motionEvent->getFlags(),
3894 motionEvent->getMetaState(),
3895 motionEvent->getButtonState(),
3896 motionEvent->getClassification(),
3897 motionEvent->getEdgeFlags(),
3898 motionEvent->getXPrecision(),
3899 motionEvent->getYPrecision(),
3900 motionEvent->getRawXCursorPosition(),
3901 motionEvent->getRawYCursorPosition(),
3902 motionEvent->getDownTime(),
3903 uint32_t(pointerCount), pointerProperties,
3904 samplePointerCoords, motionEvent->getXOffset(),
3905 motionEvent->getYOffset());
3906 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003907 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3908 sampleEventTimes += 1;
3909 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003910 std::unique_ptr<MotionEntry> nextInjectedEntry =
3911 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3912 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3913 motionEvent->getDisplayId(), policyFlags,
3914 action, actionButton, motionEvent->getFlags(),
3915 motionEvent->getMetaState(),
3916 motionEvent->getButtonState(),
3917 motionEvent->getClassification(),
3918 motionEvent->getEdgeFlags(),
3919 motionEvent->getXPrecision(),
3920 motionEvent->getYPrecision(),
3921 motionEvent->getRawXCursorPosition(),
3922 motionEvent->getRawYCursorPosition(),
3923 motionEvent->getDownTime(),
3924 uint32_t(pointerCount), pointerProperties,
3925 samplePointerCoords,
3926 motionEvent->getXOffset(),
3927 motionEvent->getYOffset());
3928 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003929 }
3930 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003931 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003932
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003933 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003934 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003935 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003936 }
3937
3938 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003939 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003940 injectionState->injectionIsAsync = true;
3941 }
3942
3943 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003944 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003945
3946 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003947 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003948 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003949 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003950 }
3951
3952 mLock.unlock();
3953
3954 if (needWake) {
3955 mLooper->wake();
3956 }
3957
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003958 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003959 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003960 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003961
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003962 if (syncMode == InputEventInjectionSync::NONE) {
3963 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003964 } else {
3965 for (;;) {
3966 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003967 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003968 break;
3969 }
3970
3971 nsecs_t remainingTimeout = endTime - now();
3972 if (remainingTimeout <= 0) {
3973#if DEBUG_INJECTION
3974 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003975 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003977 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003978 break;
3979 }
3980
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003981 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003982 }
3983
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003984 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3985 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003986 while (injectionState->pendingForegroundDispatches != 0) {
3987#if DEBUG_INJECTION
3988 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003989 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003990#endif
3991 nsecs_t remainingTimeout = endTime - now();
3992 if (remainingTimeout <= 0) {
3993#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003994 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3995 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003996#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003997 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003998 break;
3999 }
4000
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004001 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004002 }
4003 }
4004 }
4005
4006 injectionState->release();
4007 } // release lock
4008
4009#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004010 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004011 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004012#endif
4013
4014 return injectionResult;
4015}
4016
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004017std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004018 std::array<uint8_t, 32> calculatedHmac;
4019 std::unique_ptr<VerifiedInputEvent> result;
4020 switch (event.getType()) {
4021 case AINPUT_EVENT_TYPE_KEY: {
4022 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4023 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4024 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004025 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004026 break;
4027 }
4028 case AINPUT_EVENT_TYPE_MOTION: {
4029 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4030 VerifiedMotionEvent verifiedMotionEvent =
4031 verifiedMotionEventFromMotionEvent(motionEvent);
4032 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004033 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004034 break;
4035 }
4036 default: {
4037 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4038 return nullptr;
4039 }
4040 }
4041 if (calculatedHmac == INVALID_HMAC) {
4042 return nullptr;
4043 }
4044 if (calculatedHmac != event.getHmac()) {
4045 return nullptr;
4046 }
4047 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004048}
4049
Michael Wrightd02c5b62014-02-10 15:10:22 -08004050bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004051 return injectorUid == 0 ||
4052 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004053}
4054
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004055void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004056 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004057 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004058 if (injectionState) {
4059#if DEBUG_INJECTION
4060 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004061 "injectorPid=%d, injectorUid=%d",
4062 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004063#endif
4064
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004065 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004066 // Log the outcome since the injector did not wait for the injection result.
4067 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004068 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004069 ALOGV("Asynchronous input event injection succeeded.");
4070 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004071 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004072 ALOGW("Asynchronous input event injection failed.");
4073 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004074 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004075 ALOGW("Asynchronous input event injection permission denied.");
4076 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004077 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004078 ALOGW("Asynchronous input event injection timed out.");
4079 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004080 case InputEventInjectionResult::PENDING:
4081 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4082 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004083 }
4084 }
4085
4086 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004087 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004088 }
4089}
4090
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004091void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4092 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004093 if (injectionState) {
4094 injectionState->pendingForegroundDispatches += 1;
4095 }
4096}
4097
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004098void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4099 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004100 if (injectionState) {
4101 injectionState->pendingForegroundDispatches -= 1;
4102
4103 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004104 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004105 }
4106 }
4107}
4108
Vishnu Nairad321cd2020-08-20 16:40:21 -07004109const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004110 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004111 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
4112 auto it = mWindowHandlesByDisplay.find(displayId);
4113 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004114}
4115
Michael Wrightd02c5b62014-02-10 15:10:22 -08004116sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004117 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004118 if (windowHandleToken == nullptr) {
4119 return nullptr;
4120 }
4121
Arthur Hungb92218b2018-08-14 12:00:21 +08004122 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004123 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004124 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004125 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004126 return windowHandle;
4127 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004128 }
4129 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004130 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004131}
4132
Vishnu Nairad321cd2020-08-20 16:40:21 -07004133sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4134 int displayId) const {
4135 if (windowHandleToken == nullptr) {
4136 return nullptr;
4137 }
4138
4139 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
4140 if (windowHandle->getToken() == windowHandleToken) {
4141 return windowHandle;
4142 }
4143 }
4144 return nullptr;
4145}
4146
4147sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Vishnu Nairc519ff72021-01-21 08:23:08 -08004148 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004149 return getWindowHandleLocked(focusedToken, displayId);
4150}
4151
Mady Mellor017bcd12020-06-23 19:12:00 +00004152bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
4153 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004154 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00004155 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004156 if (handle->getId() == windowHandle->getId() &&
4157 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004158 if (windowHandle->getInfo()->displayId != it.first) {
4159 ALOGE("Found window %s in display %" PRId32
4160 ", but it should belong to display %" PRId32,
4161 windowHandle->getName().c_str(), it.first,
4162 windowHandle->getInfo()->displayId);
4163 }
4164 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08004165 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004166 }
4167 }
4168 return false;
4169}
4170
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004171bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
4172 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4173 const bool noInputChannel =
4174 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4175 if (connection != nullptr && noInputChannel) {
4176 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4177 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4178 return false;
4179 }
4180
4181 if (connection == nullptr) {
4182 if (!noInputChannel) {
4183 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4184 }
4185 return false;
4186 }
4187 if (!connection->responsive) {
4188 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4189 return false;
4190 }
4191 return true;
4192}
4193
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004194std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4195 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07004196 size_t count = mInputChannelsByToken.count(token);
4197 if (count == 0) {
4198 return nullptr;
4199 }
4200 return mInputChannelsByToken.at(token);
4201}
4202
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004203void InputDispatcher::updateWindowHandlesForDisplayLocked(
4204 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
4205 if (inputWindowHandles.empty()) {
4206 // Remove all handles on a display if there are no windows left.
4207 mWindowHandlesByDisplay.erase(displayId);
4208 return;
4209 }
4210
4211 // Since we compare the pointer of input window handles across window updates, we need
4212 // to make sure the handle object for the same window stays unchanged across updates.
4213 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07004214 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004215 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004216 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004217 }
4218
4219 std::vector<sp<InputWindowHandle>> newHandles;
4220 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
4221 if (!handle->updateInfo()) {
4222 // handle no longer valid
4223 continue;
4224 }
4225
4226 const InputWindowInfo* info = handle->getInfo();
4227 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4228 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4229 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01004230 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4231 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
4232 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004233 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004234 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004235 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004236 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004237 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004238 }
4239
4240 if (info->displayId != displayId) {
4241 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4242 handle->getName().c_str(), displayId, info->displayId);
4243 continue;
4244 }
4245
Robert Carredd13602020-04-13 17:24:34 -07004246 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4247 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004248 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004249 oldHandle->updateFrom(handle);
4250 newHandles.push_back(oldHandle);
4251 } else {
4252 newHandles.push_back(handle);
4253 }
4254 }
4255
4256 // Insert or replace
4257 mWindowHandlesByDisplay[displayId] = newHandles;
4258}
4259
Arthur Hung72d8dc32020-03-28 00:48:39 +00004260void InputDispatcher::setInputWindows(
4261 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4262 { // acquire lock
4263 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004264 for (const auto& [displayId, handles] : handlesPerDisplay) {
4265 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004266 }
4267 }
4268 // Wake up poll loop since it may need to make new input dispatching choices.
4269 mLooper->wake();
4270}
4271
Arthur Hungb92218b2018-08-14 12:00:21 +08004272/**
4273 * Called from InputManagerService, update window handle list by displayId that can receive input.
4274 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4275 * If set an empty list, remove all handles from the specific display.
4276 * For focused handle, check if need to change and send a cancel event to previous one.
4277 * For removed handle, check if need to send a cancel event if already in touch.
4278 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004279void InputDispatcher::setInputWindowsLocked(
4280 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004281 if (DEBUG_FOCUS) {
4282 std::string windowList;
4283 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4284 windowList += iwh->getName() + " ";
4285 }
4286 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4287 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004288
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004289 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4290 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4291 const bool noInputWindow =
4292 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4293 if (noInputWindow && window->getToken() != nullptr) {
4294 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4295 window->getName().c_str());
4296 window->releaseChannel();
4297 }
4298 }
4299
Arthur Hung72d8dc32020-03-28 00:48:39 +00004300 // Copy old handles for release if they are no longer present.
4301 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004302
Arthur Hung72d8dc32020-03-28 00:48:39 +00004303 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004304
Vishnu Nair958da932020-08-21 17:12:37 -07004305 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4306 if (mLastHoverWindowHandle &&
4307 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4308 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004309 mLastHoverWindowHandle = nullptr;
4310 }
4311
Vishnu Nairc519ff72021-01-21 08:23:08 -08004312 std::optional<FocusResolver::FocusChanges> changes =
4313 mFocusResolver.setInputWindows(displayId, windowHandles);
4314 if (changes) {
4315 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004316 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004317
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004318 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4319 mTouchStatesByDisplay.find(displayId);
4320 if (stateIt != mTouchStatesByDisplay.end()) {
4321 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004322 for (size_t i = 0; i < state.windows.size();) {
4323 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004324 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004325 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004326 ALOGD("Touched window was removed: %s in display %" PRId32,
4327 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004328 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004329 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004330 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4331 if (touchedInputChannel != nullptr) {
4332 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4333 "touched window was removed");
4334 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004335 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004336 state.windows.erase(state.windows.begin() + i);
4337 } else {
4338 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004339 }
4340 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004341 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004342
Arthur Hung72d8dc32020-03-28 00:48:39 +00004343 // Release information for windows that are no longer present.
4344 // This ensures that unused input channels are released promptly.
4345 // Otherwise, they might stick around until the window handle is destroyed
4346 // which might not happen until the next GC.
4347 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004348 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004349 if (DEBUG_FOCUS) {
4350 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004351 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004352 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004353 // To avoid making too many calls into the compat framework, only
4354 // check for window flags when windows are going away.
4355 // TODO(b/157929241) : delete this. This is only needed temporarily
4356 // in order to gather some data about the flag usage
4357 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4358 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4359 oldWindowHandle->getName().c_str());
4360 if (mCompatService != nullptr) {
4361 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4362 oldWindowHandle->getInfo()->ownerUid);
4363 }
4364 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004365 }
chaviw291d88a2019-02-14 10:33:58 -08004366 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004367}
4368
4369void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004370 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004371 if (DEBUG_FOCUS) {
4372 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4373 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4374 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004375 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004376 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004377
Chris Yea209fde2020-07-22 13:54:51 -07004378 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004379 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004380
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004381 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4382 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004383 }
4384
Chris Yea209fde2020-07-22 13:54:51 -07004385 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004386 if (inputApplicationHandle != nullptr) {
4387 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4388 } else {
4389 mFocusedApplicationHandlesByDisplay.erase(displayId);
4390 }
4391
4392 // No matter what the old focused application was, stop waiting on it because it is
4393 // no longer focused.
4394 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004395 } // release lock
4396
4397 // Wake up poll loop since it may need to make new input dispatching choices.
4398 mLooper->wake();
4399}
4400
Tiger Huang721e26f2018-07-24 22:26:19 +08004401/**
4402 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4403 * the display not specified.
4404 *
4405 * We track any unreleased events for each window. If a window loses the ability to receive the
4406 * released event, we will send a cancel event to it. So when the focused display is changed, we
4407 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4408 * display. The display-specified events won't be affected.
4409 */
4410void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004411 if (DEBUG_FOCUS) {
4412 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4413 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004414 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004415 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004416
4417 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004418 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004419 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004420 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004421 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004422 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004423 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004424 CancelationOptions
4425 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4426 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004427 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004428 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4429 }
4430 }
4431 mFocusedDisplayId = displayId;
4432
Chris Ye3c2d6f52020-08-09 10:39:48 -07004433 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004434 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004435 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004436
Vishnu Nairad321cd2020-08-20 16:40:21 -07004437 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004438 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004439 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004440 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004441 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004442 }
4443 }
4444 }
4445
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004446 if (DEBUG_FOCUS) {
4447 logDispatchStateLocked();
4448 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004449 } // release lock
4450
4451 // Wake up poll loop since it may need to make new input dispatching choices.
4452 mLooper->wake();
4453}
4454
Michael Wrightd02c5b62014-02-10 15:10:22 -08004455void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004456 if (DEBUG_FOCUS) {
4457 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4458 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004459
4460 bool changed;
4461 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004462 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004463
4464 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4465 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004466 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004467 }
4468
4469 if (mDispatchEnabled && !enabled) {
4470 resetAndDropEverythingLocked("dispatcher is being disabled");
4471 }
4472
4473 mDispatchEnabled = enabled;
4474 mDispatchFrozen = frozen;
4475 changed = true;
4476 } else {
4477 changed = false;
4478 }
4479
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004480 if (DEBUG_FOCUS) {
4481 logDispatchStateLocked();
4482 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004483 } // release lock
4484
4485 if (changed) {
4486 // Wake up poll loop since it may need to make new input dispatching choices.
4487 mLooper->wake();
4488 }
4489}
4490
4491void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004492 if (DEBUG_FOCUS) {
4493 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4494 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004495
4496 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004497 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004498
4499 if (mInputFilterEnabled == enabled) {
4500 return;
4501 }
4502
4503 mInputFilterEnabled = enabled;
4504 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4505 } // release lock
4506
4507 // Wake up poll loop since there might be work to do to drop everything.
4508 mLooper->wake();
4509}
4510
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004511void InputDispatcher::setInTouchMode(bool inTouchMode) {
4512 std::scoped_lock lock(mLock);
4513 mInTouchMode = inTouchMode;
4514}
4515
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004516void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4517 if (opacity < 0 || opacity > 1) {
4518 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4519 return;
4520 }
4521
4522 std::scoped_lock lock(mLock);
4523 mMaximumObscuringOpacityForTouch = opacity;
4524}
4525
4526void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4527 std::scoped_lock lock(mLock);
4528 mBlockUntrustedTouchesMode = mode;
4529}
4530
chaviwfbe5d9c2018-12-26 12:23:37 -08004531bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4532 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004533 if (DEBUG_FOCUS) {
4534 ALOGD("Trivial transfer to same window.");
4535 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004536 return true;
4537 }
4538
Michael Wrightd02c5b62014-02-10 15:10:22 -08004539 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004540 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004541
chaviwfbe5d9c2018-12-26 12:23:37 -08004542 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4543 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004544 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004545 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004546 return false;
4547 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004548 if (DEBUG_FOCUS) {
4549 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4550 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4551 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004552 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004553 if (DEBUG_FOCUS) {
4554 ALOGD("Cannot transfer focus because windows are on different displays.");
4555 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004556 return false;
4557 }
4558
4559 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004560 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4561 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004562 for (size_t i = 0; i < state.windows.size(); i++) {
4563 const TouchedWindow& touchedWindow = state.windows[i];
4564 if (touchedWindow.windowHandle == fromWindowHandle) {
4565 int32_t oldTargetFlags = touchedWindow.targetFlags;
4566 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004567
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004568 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004569
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004570 int32_t newTargetFlags = oldTargetFlags &
4571 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4572 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004573 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004574
Jeff Brownf086ddb2014-02-11 14:28:48 -08004575 found = true;
4576 goto Found;
4577 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004578 }
4579 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004580 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004581
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004582 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004583 if (DEBUG_FOCUS) {
4584 ALOGD("Focus transfer failed because from window did not have focus.");
4585 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004586 return false;
4587 }
4588
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004589 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4590 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004591 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004592 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004593 CancelationOptions
4594 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4595 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004596 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004597 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004598 }
4599
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004600 if (DEBUG_FOCUS) {
4601 logDispatchStateLocked();
4602 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004603 } // release lock
4604
4605 // Wake up poll loop since it may need to make new input dispatching choices.
4606 mLooper->wake();
4607 return true;
4608}
4609
4610void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004611 if (DEBUG_FOCUS) {
4612 ALOGD("Resetting and dropping all events (%s).", reason);
4613 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004614
4615 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4616 synthesizeCancelationEventsForAllConnectionsLocked(options);
4617
4618 resetKeyRepeatLocked();
4619 releasePendingEventLocked();
4620 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004621 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004622
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004623 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004624 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004625 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004626 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004627}
4628
4629void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004630 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004631 dumpDispatchStateLocked(dump);
4632
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004633 std::istringstream stream(dump);
4634 std::string line;
4635
4636 while (std::getline(stream, line, '\n')) {
4637 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004638 }
4639}
4640
Prabir Pradhan99987712020-11-10 18:43:05 -08004641std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4642 std::string dump;
4643
4644 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4645 toString(mFocusedWindowRequestedPointerCapture));
4646
4647 std::string windowName = "None";
4648 if (mWindowTokenWithPointerCapture) {
4649 const sp<InputWindowHandle> captureWindowHandle =
4650 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4651 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4652 : "token has capture without window";
4653 }
4654 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4655
4656 return dump;
4657}
4658
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004659void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004660 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4661 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4662 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004663 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004664
Tiger Huang721e26f2018-07-24 22:26:19 +08004665 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4666 dump += StringPrintf(INDENT "FocusedApplications:\n");
4667 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4668 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004669 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004670 const std::chrono::duration timeout =
4671 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004672 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004673 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004674 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004675 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004676 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004677 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004678 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004679
Vishnu Nairc519ff72021-01-21 08:23:08 -08004680 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08004681 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004682
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004683 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004684 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004685 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4686 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004687 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004688 state.displayId, toString(state.down), toString(state.split),
4689 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004690 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004691 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004692 for (size_t i = 0; i < state.windows.size(); i++) {
4693 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004694 dump += StringPrintf(INDENT4
4695 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4696 i, touchedWindow.windowHandle->getName().c_str(),
4697 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004698 }
4699 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004700 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004701 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004702 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004703 dump += INDENT3 "Portal windows:\n";
4704 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004705 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004706 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4707 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004708 }
4709 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004710 }
4711 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004712 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004713 }
4714
Arthur Hungb92218b2018-08-14 12:00:21 +08004715 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004716 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004717 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004718 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004719 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004720 dump += INDENT2 "Windows:\n";
4721 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004722 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004723 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004724
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004725 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004726 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004727 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004728 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004729 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00004730 "applicationInfo.name=%s, "
4731 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004732 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004733 i, windowInfo->name.c_str(), windowInfo->id,
4734 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004735 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004736 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004737 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004738 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004739 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004740 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004741 windowInfo->frameLeft, windowInfo->frameTop,
4742 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004743 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00004744 windowInfo->applicationInfo.name.c_str(),
4745 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004746 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004747 dump += StringPrintf(", inputFeatures=%s",
4748 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004749 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004750 "ms, trustedOverlay=%s, hasToken=%s, "
4751 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004752 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004753 millis(windowInfo->dispatchingTimeout),
4754 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004755 toString(windowInfo->token != nullptr),
4756 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004757 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004758 }
4759 } else {
4760 dump += INDENT2 "Windows: <none>\n";
4761 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004762 }
4763 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004764 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004765 }
4766
Michael Wright3dd60e22019-03-27 22:06:44 +00004767 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004768 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004769 const std::vector<Monitor>& monitors = it.second;
4770 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4771 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004772 }
4773 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004774 const std::vector<Monitor>& monitors = it.second;
4775 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4776 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004777 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004778 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004779 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004780 }
4781
4782 nsecs_t currentTime = now();
4783
4784 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004785 if (!mRecentQueue.empty()) {
4786 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004787 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004788 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004789 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004790 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004791 }
4792 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004793 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004794 }
4795
4796 // Dump event currently being dispatched.
4797 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004798 dump += INDENT "PendingEvent:\n";
4799 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004800 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004801 dump += StringPrintf(", age=%" PRId64 "ms\n",
4802 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004803 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004804 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004805 }
4806
4807 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004808 if (!mInboundQueue.empty()) {
4809 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004810 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004811 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004812 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004813 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004814 }
4815 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004816 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004817 }
4818
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004819 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004820 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004821 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4822 const KeyReplacement& replacement = pair.first;
4823 int32_t newKeyCode = pair.second;
4824 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004825 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004826 }
4827 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004828 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004829 }
4830
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004831 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004832 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004833 for (const auto& pair : mConnectionsByFd) {
4834 const sp<Connection>& connection = pair.second;
4835 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004836 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004837 pair.first, connection->getInputChannelName().c_str(),
4838 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004839 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004840
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004841 if (!connection->outboundQueue.empty()) {
4842 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4843 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004844 dump += dumpQueue(connection->outboundQueue, currentTime);
4845
Michael Wrightd02c5b62014-02-10 15:10:22 -08004846 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004847 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004848 }
4849
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004850 if (!connection->waitQueue.empty()) {
4851 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4852 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004853 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004854 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004855 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004856 }
4857 }
4858 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004859 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004860 }
4861
4862 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004863 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4864 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004865 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004866 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004867 }
4868
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004869 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004870 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4871 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4872 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004873}
4874
Michael Wright3dd60e22019-03-27 22:06:44 +00004875void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4876 const size_t numMonitors = monitors.size();
4877 for (size_t i = 0; i < numMonitors; i++) {
4878 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004879 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004880 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4881 dump += "\n";
4882 }
4883}
4884
Garfield Tan15601662020-09-22 15:32:38 -07004885base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4886 const std::string& name) {
4887#if DEBUG_CHANNEL_CREATION
4888 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004889#endif
4890
Garfield Tan15601662020-09-22 15:32:38 -07004891 std::shared_ptr<InputChannel> serverChannel;
4892 std::unique_ptr<InputChannel> clientChannel;
4893 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4894
4895 if (result) {
4896 return base::Error(result) << "Failed to open input channel pair with name " << name;
4897 }
4898
Michael Wrightd02c5b62014-02-10 15:10:22 -08004899 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004900 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004901 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004902
Garfield Tan15601662020-09-22 15:32:38 -07004903 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004904 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004905 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004906
Michael Wrightd02c5b62014-02-10 15:10:22 -08004907 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4908 } // release lock
4909
4910 // Wake the looper because some connections have changed.
4911 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004912 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004913}
4914
Garfield Tan15601662020-09-22 15:32:38 -07004915base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004916 int32_t displayId, bool isGestureMonitor, const std::string& name, int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07004917 std::shared_ptr<InputChannel> serverChannel;
4918 std::unique_ptr<InputChannel> clientChannel;
4919 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4920 if (result) {
4921 return base::Error(result) << "Failed to open input channel pair with name " << name;
4922 }
4923
Michael Wright3dd60e22019-03-27 22:06:44 +00004924 { // acquire lock
4925 std::scoped_lock _l(mLock);
4926
4927 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004928 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4929 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004930 }
4931
Garfield Tan15601662020-09-22 15:32:38 -07004932 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004933
Garfield Tan15601662020-09-22 15:32:38 -07004934 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004935 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004936 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004937
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004938 auto& monitorsByDisplay =
4939 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004940 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00004941
4942 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004943 }
Garfield Tan15601662020-09-22 15:32:38 -07004944
Michael Wright3dd60e22019-03-27 22:06:44 +00004945 // Wake the looper because some connections have changed.
4946 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004947 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004948}
4949
Garfield Tan15601662020-09-22 15:32:38 -07004950status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004951 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004952 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004953
Garfield Tan15601662020-09-22 15:32:38 -07004954 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004955 if (status) {
4956 return status;
4957 }
4958 } // release lock
4959
4960 // Wake the poll loop because removing the connection may have changed the current
4961 // synchronization state.
4962 mLooper->wake();
4963 return OK;
4964}
4965
Garfield Tan15601662020-09-22 15:32:38 -07004966status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
4967 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004968 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004969 if (connection == nullptr) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004970 ALOGW("Attempted to unregister already unregistered input channel");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004971 return BAD_VALUE;
4972 }
4973
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004974 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004975 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07004976
Michael Wrightd02c5b62014-02-10 15:10:22 -08004977 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004978 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004979 }
4980
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004981 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004982
4983 nsecs_t currentTime = now();
4984 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4985
4986 connection->status = Connection::STATUS_ZOMBIE;
4987 return OK;
4988}
4989
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004990void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
4991 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
4992 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00004993}
4994
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004995void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004996 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00004997 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004998 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004999 std::vector<Monitor>& monitors = it->second;
5000 const size_t numMonitors = monitors.size();
5001 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005002 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005003 monitors.erase(monitors.begin() + i);
5004 break;
5005 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005006 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005007 if (monitors.empty()) {
5008 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005009 } else {
5010 ++it;
5011 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005012 }
5013}
5014
Michael Wright3dd60e22019-03-27 22:06:44 +00005015status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5016 { // acquire lock
5017 std::scoped_lock _l(mLock);
5018 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5019
5020 if (!foundDisplayId) {
5021 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5022 return BAD_VALUE;
5023 }
5024 int32_t displayId = foundDisplayId.value();
5025
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005026 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5027 mTouchStatesByDisplay.find(displayId);
5028 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005029 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5030 return BAD_VALUE;
5031 }
5032
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005033 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00005034 std::optional<int32_t> foundDeviceId;
5035 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005036 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005037 foundDeviceId = state.deviceId;
5038 }
5039 }
5040 if (!foundDeviceId || !state.down) {
5041 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005042 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005043 return BAD_VALUE;
5044 }
5045 int32_t deviceId = foundDeviceId.value();
5046
5047 // Send cancel events to all the input channels we're stealing from.
5048 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005049 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005050 options.deviceId = deviceId;
5051 options.displayId = displayId;
5052 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005053 std::shared_ptr<InputChannel> channel =
5054 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005055 if (channel != nullptr) {
5056 synthesizeCancelationEventsForInputChannelLocked(channel, options);
5057 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005058 }
5059 // Then clear the current touch state so we stop dispatching to them as well.
5060 state.filterNonMonitors();
5061 }
5062 return OK;
5063}
5064
Prabir Pradhan99987712020-11-10 18:43:05 -08005065void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5066 { // acquire lock
5067 std::scoped_lock _l(mLock);
5068 if (DEBUG_FOCUS) {
5069 const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
5070 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5071 windowHandle != nullptr ? windowHandle->getName().c_str()
5072 : "token without window");
5073 }
5074
Vishnu Nairc519ff72021-01-21 08:23:08 -08005075 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005076 if (focusedToken != windowToken) {
5077 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5078 enabled ? "enable" : "disable");
5079 return;
5080 }
5081
5082 if (enabled == mFocusedWindowRequestedPointerCapture) {
5083 ALOGW("Ignoring request to %s Pointer Capture: "
5084 "window has %s requested pointer capture.",
5085 enabled ? "enable" : "disable", enabled ? "already" : "not");
5086 return;
5087 }
5088
5089 mFocusedWindowRequestedPointerCapture = enabled;
5090 setPointerCaptureLocked(enabled);
5091 } // release lock
5092
5093 // Wake the thread to process command entries.
5094 mLooper->wake();
5095}
5096
Michael Wright3dd60e22019-03-27 22:06:44 +00005097std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5098 const sp<IBinder>& token) {
5099 for (const auto& it : mGestureMonitorsByDisplay) {
5100 const std::vector<Monitor>& monitors = it.second;
5101 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005102 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005103 return it.first;
5104 }
5105 }
5106 }
5107 return std::nullopt;
5108}
5109
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005110std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5111 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5112 if (gesturePid.has_value()) {
5113 return gesturePid;
5114 }
5115 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5116}
5117
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005118sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005119 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005120 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005121 }
5122
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005123 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005124 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005125 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005126 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005127 }
5128 }
Robert Carr4e670e52018-08-15 13:26:12 -07005129
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005130 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005131}
5132
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005133std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5134 sp<Connection> connection = getConnectionLocked(connectionToken);
5135 if (connection == nullptr) {
5136 return "<nullptr>";
5137 }
5138 return connection->getInputChannelName();
5139}
5140
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005141void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005142 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005143 removeByValue(mConnectionsByFd, connection);
5144}
5145
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005146void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5147 const sp<Connection>& connection, uint32_t seq,
5148 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005149 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5150 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005151 commandEntry->connection = connection;
5152 commandEntry->eventTime = currentTime;
5153 commandEntry->seq = seq;
5154 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005155 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005156}
5157
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005158void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5159 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005160 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005161 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005162
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005163 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5164 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005165 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005166 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005167}
5168
Vishnu Nairad321cd2020-08-20 16:40:21 -07005169void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5170 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005171 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5172 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005173 commandEntry->oldToken = oldToken;
5174 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005175 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005176}
5177
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005178void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5179 if (connection == nullptr) {
5180 LOG_ALWAYS_FATAL("Caller must check for nullness");
5181 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005182 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5183 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005184 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005185 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005186 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005187 return;
5188 }
5189 /**
5190 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5191 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5192 * has changed. This could cause newer entries to time out before the already dispatched
5193 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5194 * processes the events linearly. So providing information about the oldest entry seems to be
5195 * most useful.
5196 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005197 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005198 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5199 std::string reason =
5200 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005201 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005202 ns2ms(currentWait),
5203 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005204 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005205 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005206
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005207 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5208
5209 // Stop waking up for events on this connection, it is already unresponsive
5210 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005211}
5212
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005213void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5214 std::string reason =
5215 StringPrintf("%s does not have a focused window", application->getName().c_str());
5216 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005217
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005218 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5219 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5220 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005221 postCommandLocked(std::move(commandEntry));
5222}
5223
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005224void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5225 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5226 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5227 commandEntry->obscuringPackage = obscuringPackage;
5228 postCommandLocked(std::move(commandEntry));
5229}
5230
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005231void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
5232 const std::string& reason) {
5233 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5234 updateLastAnrStateLocked(windowLabel, reason);
5235}
5236
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005237void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5238 const std::string& reason) {
5239 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005240 updateLastAnrStateLocked(windowLabel, reason);
5241}
5242
5243void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5244 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005245 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005246 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005247 struct tm tm;
5248 localtime_r(&t, &tm);
5249 char timestr[64];
5250 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005251 mLastAnrState.clear();
5252 mLastAnrState += INDENT "ANR:\n";
5253 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005254 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5255 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005256 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005257}
5258
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005259void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005260 mLock.unlock();
5261
5262 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5263
5264 mLock.lock();
5265}
5266
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005267void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005268 sp<Connection> connection = commandEntry->connection;
5269
5270 if (connection->status != Connection::STATUS_ZOMBIE) {
5271 mLock.unlock();
5272
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005273 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005274
5275 mLock.lock();
5276 }
5277}
5278
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005279void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005280 sp<IBinder> oldToken = commandEntry->oldToken;
5281 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005282 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005283 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005284 mLock.lock();
5285}
5286
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005287void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005288 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005289
5290 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5291
5292 mLock.lock();
5293}
5294
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005295void InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005296 mLock.unlock();
5297
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005298 mPolicy->notifyWindowUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005299
5300 mLock.lock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005301}
5302
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005303void InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005304 mLock.unlock();
5305
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005306 mPolicy->notifyMonitorUnresponsive(commandEntry->pid, commandEntry->reason);
5307
5308 mLock.lock();
5309}
5310
5311void InputDispatcher::doNotifyWindowResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5312 mLock.unlock();
5313
5314 mPolicy->notifyWindowResponsive(commandEntry->connectionToken);
5315
5316 mLock.lock();
5317}
5318
5319void InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5320 mLock.unlock();
5321
5322 mPolicy->notifyMonitorResponsive(commandEntry->pid);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005323
5324 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005325}
5326
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005327void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5328 mLock.unlock();
5329
5330 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5331
5332 mLock.lock();
5333}
5334
Michael Wrightd02c5b62014-02-10 15:10:22 -08005335void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5336 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005337 KeyEntry& entry = *(commandEntry->keyEntry);
5338 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005339
5340 mLock.unlock();
5341
Michael Wright2b3c3302018-03-02 17:19:13 +00005342 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005343 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005344 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005345 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5346 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005347 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005348 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005349
5350 mLock.lock();
5351
5352 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005353 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005354 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005355 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005356 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005357 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5358 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005359 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005360}
5361
chaviwfd6d3512019-03-25 13:23:49 -07005362void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5363 mLock.unlock();
5364 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5365 mLock.lock();
5366}
5367
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005368/**
5369 * Connection is responsive if it has no events in the waitQueue that are older than the
5370 * current time.
5371 */
5372static bool isConnectionResponsive(const Connection& connection) {
5373 const nsecs_t currentTime = now();
5374 for (const DispatchEntry* entry : connection.waitQueue) {
5375 if (entry->timeoutTime < currentTime) {
5376 return false;
5377 }
5378 }
5379 return true;
5380}
5381
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005382void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005383 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005384 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005385 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005386 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005387
5388 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005389 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005390 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005391 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005392 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005393 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005394 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005395 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005396 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5397 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005398 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005399 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005400
5401 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005402 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005403 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005404 restartEvent =
5405 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005406 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005407 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005408 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5409 handled);
5410 } else {
5411 restartEvent = false;
5412 }
5413
5414 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005415 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005416 // contents of the wait queue to have been drained, so we need to double-check
5417 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005418 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5419 if (dispatchEntryIt != connection->waitQueue.end()) {
5420 dispatchEntry = *dispatchEntryIt;
5421 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005422 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5423 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005424 if (!connection->responsive) {
5425 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005426 if (connection->responsive) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005427 // The connection was unresponsive, and now it's responsive.
5428 processConnectionResponsiveLocked(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005429 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005430 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005431 traceWaitQueueLength(connection);
5432 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005433 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005434 traceOutboundQueueLength(connection);
5435 } else {
5436 releaseDispatchEntry(dispatchEntry);
5437 }
5438 }
5439
5440 // Start the next dispatch cycle for this connection.
5441 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005442}
5443
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005444void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
5445 std::unique_ptr<CommandEntry> monitorUnresponsiveCommand = std::make_unique<CommandEntry>(
5446 &InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible);
5447 monitorUnresponsiveCommand->pid = pid;
5448 monitorUnresponsiveCommand->reason = std::move(reason);
5449 postCommandLocked(std::move(monitorUnresponsiveCommand));
5450}
5451
5452void InputDispatcher::sendWindowUnresponsiveCommandLocked(sp<IBinder> connectionToken,
5453 std::string reason) {
5454 std::unique_ptr<CommandEntry> windowUnresponsiveCommand = std::make_unique<CommandEntry>(
5455 &InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible);
5456 windowUnresponsiveCommand->connectionToken = std::move(connectionToken);
5457 windowUnresponsiveCommand->reason = std::move(reason);
5458 postCommandLocked(std::move(windowUnresponsiveCommand));
5459}
5460
5461void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
5462 std::unique_ptr<CommandEntry> monitorResponsiveCommand = std::make_unique<CommandEntry>(
5463 &InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible);
5464 monitorResponsiveCommand->pid = pid;
5465 postCommandLocked(std::move(monitorResponsiveCommand));
5466}
5467
5468void InputDispatcher::sendWindowResponsiveCommandLocked(sp<IBinder> connectionToken) {
5469 std::unique_ptr<CommandEntry> windowResponsiveCommand = std::make_unique<CommandEntry>(
5470 &InputDispatcher::doNotifyWindowResponsiveLockedInterruptible);
5471 windowResponsiveCommand->connectionToken = std::move(connectionToken);
5472 postCommandLocked(std::move(windowResponsiveCommand));
5473}
5474
5475/**
5476 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5477 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5478 * command entry to the command queue.
5479 */
5480void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5481 std::string reason) {
5482 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5483 if (connection.monitor) {
5484 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5485 reason.c_str());
5486 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5487 if (!pid.has_value()) {
5488 ALOGE("Could not find unresponsive monitor for connection %s",
5489 connection.inputChannel->getName().c_str());
5490 return;
5491 }
5492 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5493 return;
5494 }
5495 // If not a monitor, must be a window
5496 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5497 reason.c_str());
5498 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5499}
5500
5501/**
5502 * Tell the policy that a connection has become responsive so that it can stop ANR.
5503 */
5504void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5505 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5506 if (connection.monitor) {
5507 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5508 if (!pid.has_value()) {
5509 ALOGE("Could not find responsive monitor for connection %s",
5510 connection.inputChannel->getName().c_str());
5511 return;
5512 }
5513 sendMonitorResponsiveCommandLocked(pid.value());
5514 return;
5515 }
5516 // If not a monitor, must be a window
5517 sendWindowResponsiveCommandLocked(connectionToken);
5518}
5519
Michael Wrightd02c5b62014-02-10 15:10:22 -08005520bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005521 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005522 KeyEntry& keyEntry, bool handled) {
5523 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005524 if (!handled) {
5525 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005526 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005527 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005528 return false;
5529 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005530
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005531 // Get the fallback key state.
5532 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005533 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005534 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005535 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005536 connection->inputState.removeFallbackKey(originalKeyCode);
5537 }
5538
5539 if (handled || !dispatchEntry->hasForegroundTarget()) {
5540 // If the application handles the original key for which we previously
5541 // generated a fallback or if the window is not a foreground window,
5542 // then cancel the associated fallback key, if any.
5543 if (fallbackKeyCode != -1) {
5544 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005545#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005546 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005547 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005548 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005549#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005550 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005551 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005552
5553 mLock.unlock();
5554
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005555 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005556 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005557
5558 mLock.lock();
5559
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005560 // Cancel the fallback key.
5561 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005562 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005563 "application handled the original non-fallback key "
5564 "or is no longer a foreground target, "
5565 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005566 options.keyCode = fallbackKeyCode;
5567 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005568 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005569 connection->inputState.removeFallbackKey(originalKeyCode);
5570 }
5571 } else {
5572 // If the application did not handle a non-fallback key, first check
5573 // that we are in a good state to perform unhandled key event processing
5574 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005575 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005576 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005577#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005578 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005579 "since this is not an initial down. "
5580 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005581 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005582#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005583 return false;
5584 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005585
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005586 // Dispatch the unhandled key to the policy.
5587#if DEBUG_OUTBOUND_EVENT_DETAILS
5588 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005589 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005590 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005591#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005592 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005593
5594 mLock.unlock();
5595
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005596 bool fallback =
5597 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005598 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005599
5600 mLock.lock();
5601
5602 if (connection->status != Connection::STATUS_NORMAL) {
5603 connection->inputState.removeFallbackKey(originalKeyCode);
5604 return false;
5605 }
5606
5607 // Latch the fallback keycode for this key on an initial down.
5608 // The fallback keycode cannot change at any other point in the lifecycle.
5609 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005610 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005611 fallbackKeyCode = event.getKeyCode();
5612 } else {
5613 fallbackKeyCode = AKEYCODE_UNKNOWN;
5614 }
5615 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5616 }
5617
5618 ALOG_ASSERT(fallbackKeyCode != -1);
5619
5620 // Cancel the fallback key if the policy decides not to send it anymore.
5621 // We will continue to dispatch the key to the policy but we will no
5622 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005623 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5624 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005625#if DEBUG_OUTBOUND_EVENT_DETAILS
5626 if (fallback) {
5627 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005628 "as a fallback for %d, but on the DOWN it had requested "
5629 "to send %d instead. Fallback canceled.",
5630 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005631 } else {
5632 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005633 "but on the DOWN it had requested to send %d. "
5634 "Fallback canceled.",
5635 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005636 }
5637#endif
5638
5639 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5640 "canceling fallback, policy no longer desires it");
5641 options.keyCode = fallbackKeyCode;
5642 synthesizeCancelationEventsForConnectionLocked(connection, options);
5643
5644 fallback = false;
5645 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005646 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005647 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005648 }
5649 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005650
5651#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005652 {
5653 std::string msg;
5654 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5655 connection->inputState.getFallbackKeys();
5656 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005657 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005658 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005659 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005660 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005661 }
5662#endif
5663
5664 if (fallback) {
5665 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005666 keyEntry.eventTime = event.getEventTime();
5667 keyEntry.deviceId = event.getDeviceId();
5668 keyEntry.source = event.getSource();
5669 keyEntry.displayId = event.getDisplayId();
5670 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5671 keyEntry.keyCode = fallbackKeyCode;
5672 keyEntry.scanCode = event.getScanCode();
5673 keyEntry.metaState = event.getMetaState();
5674 keyEntry.repeatCount = event.getRepeatCount();
5675 keyEntry.downTime = event.getDownTime();
5676 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005677
5678#if DEBUG_OUTBOUND_EVENT_DETAILS
5679 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005680 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005681 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005682#endif
5683 return true; // restart the event
5684 } else {
5685#if DEBUG_OUTBOUND_EVENT_DETAILS
5686 ALOGD("Unhandled key event: No fallback key.");
5687#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005688
5689 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005690 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005691 }
5692 }
5693 return false;
5694}
5695
5696bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005697 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005698 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005699 return false;
5700}
5701
5702void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5703 mLock.unlock();
5704
5705 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5706
5707 mLock.lock();
5708}
5709
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005710void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5711 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005712 // TODO Write some statistics about how long we spend waiting.
5713}
5714
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005715/**
5716 * Report the touch event latency to the statsd server.
5717 * Input events are reported for statistics if:
5718 * - This is a touchscreen event
5719 * - InputFilter is not enabled
5720 * - Event is not injected or synthesized
5721 *
5722 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5723 * from getting aggregated with the "old" data.
5724 */
5725void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5726 REQUIRES(mLock) {
5727 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5728 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5729 if (!reportForStatistics) {
5730 return;
5731 }
5732
5733 if (mTouchStatistics.shouldReport()) {
5734 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5735 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5736 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5737 mTouchStatistics.reset();
5738 }
5739 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5740 mTouchStatistics.addValue(latencyMicros);
5741}
5742
Michael Wrightd02c5b62014-02-10 15:10:22 -08005743void InputDispatcher::traceInboundQueueLengthLocked() {
5744 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005745 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005746 }
5747}
5748
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005749void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005750 if (ATRACE_ENABLED()) {
5751 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005752 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005753 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005754 }
5755}
5756
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005757void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005758 if (ATRACE_ENABLED()) {
5759 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005760 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005761 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005762 }
5763}
5764
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005765void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005766 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005767
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005768 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005769 dumpDispatchStateLocked(dump);
5770
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005771 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005772 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005773 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005774 }
5775}
5776
5777void InputDispatcher::monitor() {
5778 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005779 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005780 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005781 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005782}
5783
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005784/**
5785 * Wake up the dispatcher and wait until it processes all events and commands.
5786 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5787 * this method can be safely called from any thread, as long as you've ensured that
5788 * the work you are interested in completing has already been queued.
5789 */
5790bool InputDispatcher::waitForIdle() {
5791 /**
5792 * Timeout should represent the longest possible time that a device might spend processing
5793 * events and commands.
5794 */
5795 constexpr std::chrono::duration TIMEOUT = 100ms;
5796 std::unique_lock lock(mLock);
5797 mLooper->wake();
5798 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5799 return result == std::cv_status::no_timeout;
5800}
5801
Vishnu Naire798b472020-07-23 13:52:21 -07005802/**
5803 * Sets focus to the window identified by the token. This must be called
5804 * after updating any input window handles.
5805 *
5806 * Params:
5807 * request.token - input channel token used to identify the window that should gain focus.
5808 * request.focusedToken - the token that the caller expects currently to be focused. If the
5809 * specified token does not match the currently focused window, this request will be dropped.
5810 * If the specified focused token matches the currently focused window, the call will succeed.
5811 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5812 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5813 * when requesting the focus change. This determines which request gets
5814 * precedence if there is a focus change request from another source such as pointer down.
5815 */
Vishnu Nair958da932020-08-21 17:12:37 -07005816void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5817 { // acquire lock
5818 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005819 std::optional<FocusResolver::FocusChanges> changes =
5820 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
5821 if (changes) {
5822 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07005823 }
5824 } // release lock
5825 // Wake up poll loop since it may need to make new input dispatching choices.
5826 mLooper->wake();
5827}
5828
Vishnu Nairc519ff72021-01-21 08:23:08 -08005829void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
5830 if (changes.oldFocus) {
5831 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005832 if (focusedInputChannel) {
5833 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5834 "focus left window");
5835 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005836 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005837 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005838 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08005839 if (changes.newFocus) {
5840 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005841 }
5842
Prabir Pradhan99987712020-11-10 18:43:05 -08005843 // If a window has pointer capture, then it must have focus. We need to ensure that this
5844 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
5845 // If the window loses focus before it loses pointer capture, then the window can be in a state
5846 // where it has pointer capture but not focus, violating the contract. Therefore we must
5847 // dispatch the pointer capture event before the focus event. Since focus events are added to
5848 // the front of the queue (above), we add the pointer capture event to the front of the queue
5849 // after the focus events are added. This ensures the pointer capture event ends up at the
5850 // front.
5851 disablePointerCaptureForcedLocked();
5852
Vishnu Nairc519ff72021-01-21 08:23:08 -08005853 if (mFocusedDisplayId == changes.displayId) {
5854 notifyFocusChangedLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005855 }
5856}
Vishnu Nair958da932020-08-21 17:12:37 -07005857
Prabir Pradhan99987712020-11-10 18:43:05 -08005858void InputDispatcher::disablePointerCaptureForcedLocked() {
5859 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
5860 return;
5861 }
5862
5863 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
5864
5865 if (mFocusedWindowRequestedPointerCapture) {
5866 mFocusedWindowRequestedPointerCapture = false;
5867 setPointerCaptureLocked(false);
5868 }
5869
5870 if (!mWindowTokenWithPointerCapture) {
5871 // No need to send capture changes because no window has capture.
5872 return;
5873 }
5874
5875 if (mPendingEvent != nullptr) {
5876 // Move the pending event to the front of the queue. This will give the chance
5877 // for the pending event to be dropped if it is a captured event.
5878 mInboundQueue.push_front(mPendingEvent);
5879 mPendingEvent = nullptr;
5880 }
5881
5882 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
5883 false /* hasCapture */);
5884 mInboundQueue.push_front(std::move(entry));
5885}
5886
Prabir Pradhan99987712020-11-10 18:43:05 -08005887void InputDispatcher::setPointerCaptureLocked(bool enabled) {
5888 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5889 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
5890 commandEntry->enabled = enabled;
5891 postCommandLocked(std::move(commandEntry));
5892}
5893
5894void InputDispatcher::doSetPointerCaptureLockedInterruptible(
5895 android::inputdispatcher::CommandEntry* commandEntry) {
5896 mLock.unlock();
5897
5898 mPolicy->setPointerCapture(commandEntry->enabled);
5899
5900 mLock.lock();
5901}
5902
Garfield Tane84e6f92019-08-29 17:28:41 -07005903} // namespace android::inputdispatcher