blob: 5a577d4b99e3a0c6cacae5664ad7209dd955ac8d [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
Chris Yefb552902021-02-03 17:18:37 -08003750void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
3751#if DEBUG_INBOUND_EVENT_DETAILS
3752 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
3753 args->deviceId, args->isOn);
3754#endif
3755 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
3756}
3757
Michael Wrightd02c5b62014-02-10 15:10:22 -08003758bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003759 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003760}
3761
3762void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3763#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003764 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003765 "switchMask=0x%08x",
3766 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003767#endif
3768
3769 uint32_t policyFlags = args->policyFlags;
3770 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003771 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003772}
3773
3774void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3775#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003776 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3777 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003778#endif
3779
3780 bool needWake;
3781 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003782 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003783
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003784 std::unique_ptr<DeviceResetEntry> newEntry =
3785 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3786 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003787 } // release lock
3788
3789 if (needWake) {
3790 mLooper->wake();
3791 }
3792}
3793
Prabir Pradhan7e186182020-11-10 13:56:45 -08003794void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3795#if DEBUG_INBOUND_EVENT_DETAILS
3796 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3797 args->enabled ? "true" : "false");
3798#endif
3799
Prabir Pradhan99987712020-11-10 18:43:05 -08003800 bool needWake;
3801 { // acquire lock
3802 std::scoped_lock _l(mLock);
3803 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
3804 args->enabled);
3805 needWake = enqueueInboundEventLocked(std::move(entry));
3806 } // release lock
3807
3808 if (needWake) {
3809 mLooper->wake();
3810 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003811}
3812
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003813InputEventInjectionResult InputDispatcher::injectInputEvent(
3814 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3815 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003816#if DEBUG_INBOUND_EVENT_DETAILS
3817 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003818 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3819 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003820#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003821 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003822
3823 policyFlags |= POLICY_FLAG_INJECTED;
3824 if (hasInjectionPermission(injectorPid, injectorUid)) {
3825 policyFlags |= POLICY_FLAG_TRUSTED;
3826 }
3827
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003828 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003829 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003830 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003831 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3832 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003833 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003834 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003835 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003836
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003837 int32_t flags = incomingKey.getFlags();
3838 int32_t keyCode = incomingKey.getKeyCode();
3839 int32_t metaState = incomingKey.getMetaState();
3840 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003841 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003842 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003843 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003844 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3845 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3846 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003847
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003848 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3849 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003850 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003851
3852 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3853 android::base::Timer t;
3854 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3855 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3856 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3857 std::to_string(t.duration().count()).c_str());
3858 }
3859 }
3860
3861 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003862 std::unique_ptr<KeyEntry> injectedEntry =
3863 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3864 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3865 incomingKey.getDisplayId(), policyFlags, action,
3866 flags, keyCode, incomingKey.getScanCode(), metaState,
3867 incomingKey.getRepeatCount(),
3868 incomingKey.getDownTime());
3869 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003870 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003871 }
3872
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003873 case AINPUT_EVENT_TYPE_MOTION: {
3874 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3875 int32_t action = motionEvent->getAction();
3876 size_t pointerCount = motionEvent->getPointerCount();
3877 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3878 int32_t actionButton = motionEvent->getActionButton();
3879 int32_t displayId = motionEvent->getDisplayId();
3880 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003881 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003882 }
3883
3884 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3885 nsecs_t eventTime = motionEvent->getEventTime();
3886 android::base::Timer t;
3887 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3888 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3889 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3890 std::to_string(t.duration().count()).c_str());
3891 }
3892 }
3893
3894 mLock.lock();
3895 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3896 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003897 std::unique_ptr<MotionEntry> injectedEntry =
3898 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3899 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3900 motionEvent->getDisplayId(), policyFlags, action,
3901 actionButton, motionEvent->getFlags(),
3902 motionEvent->getMetaState(),
3903 motionEvent->getButtonState(),
3904 motionEvent->getClassification(),
3905 motionEvent->getEdgeFlags(),
3906 motionEvent->getXPrecision(),
3907 motionEvent->getYPrecision(),
3908 motionEvent->getRawXCursorPosition(),
3909 motionEvent->getRawYCursorPosition(),
3910 motionEvent->getDownTime(),
3911 uint32_t(pointerCount), pointerProperties,
3912 samplePointerCoords, motionEvent->getXOffset(),
3913 motionEvent->getYOffset());
3914 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003915 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3916 sampleEventTimes += 1;
3917 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003918 std::unique_ptr<MotionEntry> nextInjectedEntry =
3919 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3920 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3921 motionEvent->getDisplayId(), policyFlags,
3922 action, actionButton, motionEvent->getFlags(),
3923 motionEvent->getMetaState(),
3924 motionEvent->getButtonState(),
3925 motionEvent->getClassification(),
3926 motionEvent->getEdgeFlags(),
3927 motionEvent->getXPrecision(),
3928 motionEvent->getYPrecision(),
3929 motionEvent->getRawXCursorPosition(),
3930 motionEvent->getRawYCursorPosition(),
3931 motionEvent->getDownTime(),
3932 uint32_t(pointerCount), pointerProperties,
3933 samplePointerCoords,
3934 motionEvent->getXOffset(),
3935 motionEvent->getYOffset());
3936 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003937 }
3938 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003939 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003940
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003941 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003942 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003943 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003944 }
3945
3946 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003947 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003948 injectionState->injectionIsAsync = true;
3949 }
3950
3951 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003952 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003953
3954 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003955 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003956 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003957 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003958 }
3959
3960 mLock.unlock();
3961
3962 if (needWake) {
3963 mLooper->wake();
3964 }
3965
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003966 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003967 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003968 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003969
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003970 if (syncMode == InputEventInjectionSync::NONE) {
3971 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003972 } else {
3973 for (;;) {
3974 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003975 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976 break;
3977 }
3978
3979 nsecs_t remainingTimeout = endTime - now();
3980 if (remainingTimeout <= 0) {
3981#if DEBUG_INJECTION
3982 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003983 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003984#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003985 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003986 break;
3987 }
3988
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003989 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003990 }
3991
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003992 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3993 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003994 while (injectionState->pendingForegroundDispatches != 0) {
3995#if DEBUG_INJECTION
3996 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003997 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003998#endif
3999 nsecs_t remainingTimeout = endTime - now();
4000 if (remainingTimeout <= 0) {
4001#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004002 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4003 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004004#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004005 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004006 break;
4007 }
4008
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004009 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004010 }
4011 }
4012 }
4013
4014 injectionState->release();
4015 } // release lock
4016
4017#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004018 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004019 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004020#endif
4021
4022 return injectionResult;
4023}
4024
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004025std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004026 std::array<uint8_t, 32> calculatedHmac;
4027 std::unique_ptr<VerifiedInputEvent> result;
4028 switch (event.getType()) {
4029 case AINPUT_EVENT_TYPE_KEY: {
4030 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4031 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4032 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004033 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004034 break;
4035 }
4036 case AINPUT_EVENT_TYPE_MOTION: {
4037 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4038 VerifiedMotionEvent verifiedMotionEvent =
4039 verifiedMotionEventFromMotionEvent(motionEvent);
4040 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004041 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004042 break;
4043 }
4044 default: {
4045 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4046 return nullptr;
4047 }
4048 }
4049 if (calculatedHmac == INVALID_HMAC) {
4050 return nullptr;
4051 }
4052 if (calculatedHmac != event.getHmac()) {
4053 return nullptr;
4054 }
4055 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004056}
4057
Michael Wrightd02c5b62014-02-10 15:10:22 -08004058bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004059 return injectorUid == 0 ||
4060 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004061}
4062
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004063void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004064 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004065 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004066 if (injectionState) {
4067#if DEBUG_INJECTION
4068 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004069 "injectorPid=%d, injectorUid=%d",
4070 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004071#endif
4072
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004073 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004074 // Log the outcome since the injector did not wait for the injection result.
4075 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004076 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004077 ALOGV("Asynchronous input event injection succeeded.");
4078 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004079 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004080 ALOGW("Asynchronous input event injection failed.");
4081 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004082 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004083 ALOGW("Asynchronous input event injection permission denied.");
4084 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004085 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004086 ALOGW("Asynchronous input event injection timed out.");
4087 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004088 case InputEventInjectionResult::PENDING:
4089 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4090 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004091 }
4092 }
4093
4094 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004095 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004096 }
4097}
4098
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004099void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4100 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004101 if (injectionState) {
4102 injectionState->pendingForegroundDispatches += 1;
4103 }
4104}
4105
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004106void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4107 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004108 if (injectionState) {
4109 injectionState->pendingForegroundDispatches -= 1;
4110
4111 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004112 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004113 }
4114 }
4115}
4116
Vishnu Nairad321cd2020-08-20 16:40:21 -07004117const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004118 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004119 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
4120 auto it = mWindowHandlesByDisplay.find(displayId);
4121 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004122}
4123
Michael Wrightd02c5b62014-02-10 15:10:22 -08004124sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004125 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004126 if (windowHandleToken == nullptr) {
4127 return nullptr;
4128 }
4129
Arthur Hungb92218b2018-08-14 12:00:21 +08004130 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004131 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004132 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004133 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004134 return windowHandle;
4135 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004136 }
4137 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004138 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004139}
4140
Vishnu Nairad321cd2020-08-20 16:40:21 -07004141sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4142 int displayId) const {
4143 if (windowHandleToken == nullptr) {
4144 return nullptr;
4145 }
4146
4147 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
4148 if (windowHandle->getToken() == windowHandleToken) {
4149 return windowHandle;
4150 }
4151 }
4152 return nullptr;
4153}
4154
4155sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Vishnu Nairc519ff72021-01-21 08:23:08 -08004156 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004157 return getWindowHandleLocked(focusedToken, displayId);
4158}
4159
Mady Mellor017bcd12020-06-23 19:12:00 +00004160bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
4161 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004162 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00004163 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004164 if (handle->getId() == windowHandle->getId() &&
4165 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004166 if (windowHandle->getInfo()->displayId != it.first) {
4167 ALOGE("Found window %s in display %" PRId32
4168 ", but it should belong to display %" PRId32,
4169 windowHandle->getName().c_str(), it.first,
4170 windowHandle->getInfo()->displayId);
4171 }
4172 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08004173 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004174 }
4175 }
4176 return false;
4177}
4178
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004179bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
4180 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4181 const bool noInputChannel =
4182 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4183 if (connection != nullptr && noInputChannel) {
4184 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4185 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4186 return false;
4187 }
4188
4189 if (connection == nullptr) {
4190 if (!noInputChannel) {
4191 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4192 }
4193 return false;
4194 }
4195 if (!connection->responsive) {
4196 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4197 return false;
4198 }
4199 return true;
4200}
4201
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004202std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4203 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07004204 size_t count = mInputChannelsByToken.count(token);
4205 if (count == 0) {
4206 return nullptr;
4207 }
4208 return mInputChannelsByToken.at(token);
4209}
4210
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004211void InputDispatcher::updateWindowHandlesForDisplayLocked(
4212 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
4213 if (inputWindowHandles.empty()) {
4214 // Remove all handles on a display if there are no windows left.
4215 mWindowHandlesByDisplay.erase(displayId);
4216 return;
4217 }
4218
4219 // Since we compare the pointer of input window handles across window updates, we need
4220 // to make sure the handle object for the same window stays unchanged across updates.
4221 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07004222 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004223 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004224 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004225 }
4226
4227 std::vector<sp<InputWindowHandle>> newHandles;
4228 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
4229 if (!handle->updateInfo()) {
4230 // handle no longer valid
4231 continue;
4232 }
4233
4234 const InputWindowInfo* info = handle->getInfo();
4235 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4236 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4237 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01004238 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4239 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
4240 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004241 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004242 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004243 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004244 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004245 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004246 }
4247
4248 if (info->displayId != displayId) {
4249 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4250 handle->getName().c_str(), displayId, info->displayId);
4251 continue;
4252 }
4253
Robert Carredd13602020-04-13 17:24:34 -07004254 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4255 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004256 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004257 oldHandle->updateFrom(handle);
4258 newHandles.push_back(oldHandle);
4259 } else {
4260 newHandles.push_back(handle);
4261 }
4262 }
4263
4264 // Insert or replace
4265 mWindowHandlesByDisplay[displayId] = newHandles;
4266}
4267
Arthur Hung72d8dc32020-03-28 00:48:39 +00004268void InputDispatcher::setInputWindows(
4269 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4270 { // acquire lock
4271 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004272 for (const auto& [displayId, handles] : handlesPerDisplay) {
4273 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004274 }
4275 }
4276 // Wake up poll loop since it may need to make new input dispatching choices.
4277 mLooper->wake();
4278}
4279
Arthur Hungb92218b2018-08-14 12:00:21 +08004280/**
4281 * Called from InputManagerService, update window handle list by displayId that can receive input.
4282 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4283 * If set an empty list, remove all handles from the specific display.
4284 * For focused handle, check if need to change and send a cancel event to previous one.
4285 * For removed handle, check if need to send a cancel event if already in touch.
4286 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004287void InputDispatcher::setInputWindowsLocked(
4288 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004289 if (DEBUG_FOCUS) {
4290 std::string windowList;
4291 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4292 windowList += iwh->getName() + " ";
4293 }
4294 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4295 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004296
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004297 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4298 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4299 const bool noInputWindow =
4300 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4301 if (noInputWindow && window->getToken() != nullptr) {
4302 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4303 window->getName().c_str());
4304 window->releaseChannel();
4305 }
4306 }
4307
Arthur Hung72d8dc32020-03-28 00:48:39 +00004308 // Copy old handles for release if they are no longer present.
4309 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004310
Arthur Hung72d8dc32020-03-28 00:48:39 +00004311 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004312
Vishnu Nair958da932020-08-21 17:12:37 -07004313 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4314 if (mLastHoverWindowHandle &&
4315 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4316 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004317 mLastHoverWindowHandle = nullptr;
4318 }
4319
Vishnu Nairc519ff72021-01-21 08:23:08 -08004320 std::optional<FocusResolver::FocusChanges> changes =
4321 mFocusResolver.setInputWindows(displayId, windowHandles);
4322 if (changes) {
4323 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004324 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004325
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004326 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4327 mTouchStatesByDisplay.find(displayId);
4328 if (stateIt != mTouchStatesByDisplay.end()) {
4329 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004330 for (size_t i = 0; i < state.windows.size();) {
4331 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004332 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004333 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004334 ALOGD("Touched window was removed: %s in display %" PRId32,
4335 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004336 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004337 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004338 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4339 if (touchedInputChannel != nullptr) {
4340 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4341 "touched window was removed");
4342 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004343 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004344 state.windows.erase(state.windows.begin() + i);
4345 } else {
4346 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004347 }
4348 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004349 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004350
Arthur Hung72d8dc32020-03-28 00:48:39 +00004351 // Release information for windows that are no longer present.
4352 // This ensures that unused input channels are released promptly.
4353 // Otherwise, they might stick around until the window handle is destroyed
4354 // which might not happen until the next GC.
4355 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004356 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004357 if (DEBUG_FOCUS) {
4358 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004359 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004360 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004361 // To avoid making too many calls into the compat framework, only
4362 // check for window flags when windows are going away.
4363 // TODO(b/157929241) : delete this. This is only needed temporarily
4364 // in order to gather some data about the flag usage
4365 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4366 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4367 oldWindowHandle->getName().c_str());
4368 if (mCompatService != nullptr) {
4369 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4370 oldWindowHandle->getInfo()->ownerUid);
4371 }
4372 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004373 }
chaviw291d88a2019-02-14 10:33:58 -08004374 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004375}
4376
4377void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004378 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004379 if (DEBUG_FOCUS) {
4380 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4381 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4382 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004383 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004384 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004385
Chris Yea209fde2020-07-22 13:54:51 -07004386 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004387 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004388
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004389 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4390 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004391 }
4392
Chris Yea209fde2020-07-22 13:54:51 -07004393 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004394 if (inputApplicationHandle != nullptr) {
4395 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4396 } else {
4397 mFocusedApplicationHandlesByDisplay.erase(displayId);
4398 }
4399
4400 // No matter what the old focused application was, stop waiting on it because it is
4401 // no longer focused.
4402 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004403 } // release lock
4404
4405 // Wake up poll loop since it may need to make new input dispatching choices.
4406 mLooper->wake();
4407}
4408
Tiger Huang721e26f2018-07-24 22:26:19 +08004409/**
4410 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4411 * the display not specified.
4412 *
4413 * We track any unreleased events for each window. If a window loses the ability to receive the
4414 * released event, we will send a cancel event to it. So when the focused display is changed, we
4415 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4416 * display. The display-specified events won't be affected.
4417 */
4418void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004419 if (DEBUG_FOCUS) {
4420 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4421 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004422 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004423 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004424
4425 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004426 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004427 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004428 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004429 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004430 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004431 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004432 CancelationOptions
4433 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4434 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004435 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004436 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4437 }
4438 }
4439 mFocusedDisplayId = displayId;
4440
Chris Ye3c2d6f52020-08-09 10:39:48 -07004441 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004442 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004443 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004444
Vishnu Nairad321cd2020-08-20 16:40:21 -07004445 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004446 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004447 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004448 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004449 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004450 }
4451 }
4452 }
4453
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004454 if (DEBUG_FOCUS) {
4455 logDispatchStateLocked();
4456 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004457 } // release lock
4458
4459 // Wake up poll loop since it may need to make new input dispatching choices.
4460 mLooper->wake();
4461}
4462
Michael Wrightd02c5b62014-02-10 15:10:22 -08004463void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004464 if (DEBUG_FOCUS) {
4465 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4466 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004467
4468 bool changed;
4469 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004470 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004471
4472 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4473 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004474 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004475 }
4476
4477 if (mDispatchEnabled && !enabled) {
4478 resetAndDropEverythingLocked("dispatcher is being disabled");
4479 }
4480
4481 mDispatchEnabled = enabled;
4482 mDispatchFrozen = frozen;
4483 changed = true;
4484 } else {
4485 changed = false;
4486 }
4487
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004488 if (DEBUG_FOCUS) {
4489 logDispatchStateLocked();
4490 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004491 } // release lock
4492
4493 if (changed) {
4494 // Wake up poll loop since it may need to make new input dispatching choices.
4495 mLooper->wake();
4496 }
4497}
4498
4499void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004500 if (DEBUG_FOCUS) {
4501 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4502 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004503
4504 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004505 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004506
4507 if (mInputFilterEnabled == enabled) {
4508 return;
4509 }
4510
4511 mInputFilterEnabled = enabled;
4512 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4513 } // release lock
4514
4515 // Wake up poll loop since there might be work to do to drop everything.
4516 mLooper->wake();
4517}
4518
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004519void InputDispatcher::setInTouchMode(bool inTouchMode) {
4520 std::scoped_lock lock(mLock);
4521 mInTouchMode = inTouchMode;
4522}
4523
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004524void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4525 if (opacity < 0 || opacity > 1) {
4526 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4527 return;
4528 }
4529
4530 std::scoped_lock lock(mLock);
4531 mMaximumObscuringOpacityForTouch = opacity;
4532}
4533
4534void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4535 std::scoped_lock lock(mLock);
4536 mBlockUntrustedTouchesMode = mode;
4537}
4538
chaviwfbe5d9c2018-12-26 12:23:37 -08004539bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4540 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004541 if (DEBUG_FOCUS) {
4542 ALOGD("Trivial transfer to same window.");
4543 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004544 return true;
4545 }
4546
Michael Wrightd02c5b62014-02-10 15:10:22 -08004547 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004548 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004549
chaviwfbe5d9c2018-12-26 12:23:37 -08004550 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4551 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004552 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004553 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004554 return false;
4555 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004556 if (DEBUG_FOCUS) {
4557 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4558 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4559 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004560 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004561 if (DEBUG_FOCUS) {
4562 ALOGD("Cannot transfer focus because windows are on different displays.");
4563 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004564 return false;
4565 }
4566
4567 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004568 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4569 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004570 for (size_t i = 0; i < state.windows.size(); i++) {
4571 const TouchedWindow& touchedWindow = state.windows[i];
4572 if (touchedWindow.windowHandle == fromWindowHandle) {
4573 int32_t oldTargetFlags = touchedWindow.targetFlags;
4574 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004575
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004576 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004577
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004578 int32_t newTargetFlags = oldTargetFlags &
4579 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4580 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004581 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004582
Jeff Brownf086ddb2014-02-11 14:28:48 -08004583 found = true;
4584 goto Found;
4585 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004586 }
4587 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004588 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004589
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004590 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004591 if (DEBUG_FOCUS) {
4592 ALOGD("Focus transfer failed because from window did not have focus.");
4593 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004594 return false;
4595 }
4596
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004597 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4598 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004599 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004600 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004601 CancelationOptions
4602 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4603 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004604 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004605 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004606 }
4607
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004608 if (DEBUG_FOCUS) {
4609 logDispatchStateLocked();
4610 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004611 } // release lock
4612
4613 // Wake up poll loop since it may need to make new input dispatching choices.
4614 mLooper->wake();
4615 return true;
4616}
4617
4618void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004619 if (DEBUG_FOCUS) {
4620 ALOGD("Resetting and dropping all events (%s).", reason);
4621 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004622
4623 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4624 synthesizeCancelationEventsForAllConnectionsLocked(options);
4625
4626 resetKeyRepeatLocked();
4627 releasePendingEventLocked();
4628 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004629 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004630
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004631 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004632 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004633 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004634 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004635}
4636
4637void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004638 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004639 dumpDispatchStateLocked(dump);
4640
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004641 std::istringstream stream(dump);
4642 std::string line;
4643
4644 while (std::getline(stream, line, '\n')) {
4645 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004646 }
4647}
4648
Prabir Pradhan99987712020-11-10 18:43:05 -08004649std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4650 std::string dump;
4651
4652 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4653 toString(mFocusedWindowRequestedPointerCapture));
4654
4655 std::string windowName = "None";
4656 if (mWindowTokenWithPointerCapture) {
4657 const sp<InputWindowHandle> captureWindowHandle =
4658 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4659 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4660 : "token has capture without window";
4661 }
4662 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4663
4664 return dump;
4665}
4666
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004667void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004668 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4669 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4670 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004671 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004672
Tiger Huang721e26f2018-07-24 22:26:19 +08004673 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4674 dump += StringPrintf(INDENT "FocusedApplications:\n");
4675 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4676 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004677 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004678 const std::chrono::duration timeout =
4679 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004680 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004681 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004682 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004683 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004684 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004685 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004686 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004687
Vishnu Nairc519ff72021-01-21 08:23:08 -08004688 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08004689 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004690
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004691 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004692 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004693 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4694 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004695 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004696 state.displayId, toString(state.down), toString(state.split),
4697 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004698 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004699 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004700 for (size_t i = 0; i < state.windows.size(); i++) {
4701 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004702 dump += StringPrintf(INDENT4
4703 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4704 i, touchedWindow.windowHandle->getName().c_str(),
4705 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004706 }
4707 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004708 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004709 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004710 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004711 dump += INDENT3 "Portal windows:\n";
4712 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004713 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004714 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4715 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004716 }
4717 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004718 }
4719 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004720 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004721 }
4722
Arthur Hungb92218b2018-08-14 12:00:21 +08004723 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004724 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004725 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004726 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004727 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004728 dump += INDENT2 "Windows:\n";
4729 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004730 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004731 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004732
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004733 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004734 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004735 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004736 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004737 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00004738 "applicationInfo.name=%s, "
4739 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004740 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004741 i, windowInfo->name.c_str(), windowInfo->id,
4742 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004743 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004744 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004745 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004746 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004747 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004748 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004749 windowInfo->frameLeft, windowInfo->frameTop,
4750 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004751 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00004752 windowInfo->applicationInfo.name.c_str(),
4753 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004754 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004755 dump += StringPrintf(", inputFeatures=%s",
4756 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004757 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004758 "ms, trustedOverlay=%s, hasToken=%s, "
4759 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004760 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004761 millis(windowInfo->dispatchingTimeout),
4762 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004763 toString(windowInfo->token != nullptr),
4764 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004765 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004766 }
4767 } else {
4768 dump += INDENT2 "Windows: <none>\n";
4769 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004770 }
4771 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004772 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004773 }
4774
Michael Wright3dd60e22019-03-27 22:06:44 +00004775 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004776 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004777 const std::vector<Monitor>& monitors = it.second;
4778 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4779 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004780 }
4781 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004782 const std::vector<Monitor>& monitors = it.second;
4783 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4784 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004785 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004786 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004787 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004788 }
4789
4790 nsecs_t currentTime = now();
4791
4792 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004793 if (!mRecentQueue.empty()) {
4794 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004795 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004796 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004797 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004798 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004799 }
4800 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004801 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004802 }
4803
4804 // Dump event currently being dispatched.
4805 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004806 dump += INDENT "PendingEvent:\n";
4807 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004808 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004809 dump += StringPrintf(", age=%" PRId64 "ms\n",
4810 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004811 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004812 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004813 }
4814
4815 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004816 if (!mInboundQueue.empty()) {
4817 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004818 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004819 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004820 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004821 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004822 }
4823 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004824 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004825 }
4826
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004827 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004828 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004829 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4830 const KeyReplacement& replacement = pair.first;
4831 int32_t newKeyCode = pair.second;
4832 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004833 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004834 }
4835 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004836 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004837 }
4838
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004839 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004840 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004841 for (const auto& pair : mConnectionsByFd) {
4842 const sp<Connection>& connection = pair.second;
4843 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004844 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004845 pair.first, connection->getInputChannelName().c_str(),
4846 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004847 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004848
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004849 if (!connection->outboundQueue.empty()) {
4850 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4851 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004852 dump += dumpQueue(connection->outboundQueue, currentTime);
4853
Michael Wrightd02c5b62014-02-10 15:10:22 -08004854 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004855 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004856 }
4857
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004858 if (!connection->waitQueue.empty()) {
4859 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4860 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004861 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004862 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004863 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004864 }
4865 }
4866 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004867 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004868 }
4869
4870 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004871 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4872 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004873 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004874 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004875 }
4876
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004877 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004878 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4879 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4880 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004881}
4882
Michael Wright3dd60e22019-03-27 22:06:44 +00004883void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4884 const size_t numMonitors = monitors.size();
4885 for (size_t i = 0; i < numMonitors; i++) {
4886 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004887 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004888 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4889 dump += "\n";
4890 }
4891}
4892
Garfield Tan15601662020-09-22 15:32:38 -07004893base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4894 const std::string& name) {
4895#if DEBUG_CHANNEL_CREATION
4896 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004897#endif
4898
Garfield Tan15601662020-09-22 15:32:38 -07004899 std::shared_ptr<InputChannel> serverChannel;
4900 std::unique_ptr<InputChannel> clientChannel;
4901 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4902
4903 if (result) {
4904 return base::Error(result) << "Failed to open input channel pair with name " << name;
4905 }
4906
Michael Wrightd02c5b62014-02-10 15:10:22 -08004907 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004908 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004909 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004910
Garfield Tan15601662020-09-22 15:32:38 -07004911 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004912 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004913 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004914
Michael Wrightd02c5b62014-02-10 15:10:22 -08004915 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4916 } // release lock
4917
4918 // Wake the looper because some connections have changed.
4919 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004920 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004921}
4922
Garfield Tan15601662020-09-22 15:32:38 -07004923base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004924 int32_t displayId, bool isGestureMonitor, const std::string& name, int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07004925 std::shared_ptr<InputChannel> serverChannel;
4926 std::unique_ptr<InputChannel> clientChannel;
4927 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4928 if (result) {
4929 return base::Error(result) << "Failed to open input channel pair with name " << name;
4930 }
4931
Michael Wright3dd60e22019-03-27 22:06:44 +00004932 { // acquire lock
4933 std::scoped_lock _l(mLock);
4934
4935 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004936 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4937 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004938 }
4939
Garfield Tan15601662020-09-22 15:32:38 -07004940 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004941
Garfield Tan15601662020-09-22 15:32:38 -07004942 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004943 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004944 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004945
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004946 auto& monitorsByDisplay =
4947 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004948 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00004949
4950 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004951 }
Garfield Tan15601662020-09-22 15:32:38 -07004952
Michael Wright3dd60e22019-03-27 22:06:44 +00004953 // Wake the looper because some connections have changed.
4954 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004955 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004956}
4957
Garfield Tan15601662020-09-22 15:32:38 -07004958status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004959 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004960 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004961
Garfield Tan15601662020-09-22 15:32:38 -07004962 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004963 if (status) {
4964 return status;
4965 }
4966 } // release lock
4967
4968 // Wake the poll loop because removing the connection may have changed the current
4969 // synchronization state.
4970 mLooper->wake();
4971 return OK;
4972}
4973
Garfield Tan15601662020-09-22 15:32:38 -07004974status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
4975 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004976 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004977 if (connection == nullptr) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004978 ALOGW("Attempted to unregister already unregistered input channel");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004979 return BAD_VALUE;
4980 }
4981
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004982 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004983 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07004984
Michael Wrightd02c5b62014-02-10 15:10:22 -08004985 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004986 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004987 }
4988
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004989 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004990
4991 nsecs_t currentTime = now();
4992 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4993
4994 connection->status = Connection::STATUS_ZOMBIE;
4995 return OK;
4996}
4997
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004998void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
4999 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5000 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005001}
5002
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005003void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005004 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005005 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005006 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005007 std::vector<Monitor>& monitors = it->second;
5008 const size_t numMonitors = monitors.size();
5009 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005010 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005011 monitors.erase(monitors.begin() + i);
5012 break;
5013 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005014 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005015 if (monitors.empty()) {
5016 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005017 } else {
5018 ++it;
5019 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005020 }
5021}
5022
Michael Wright3dd60e22019-03-27 22:06:44 +00005023status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5024 { // acquire lock
5025 std::scoped_lock _l(mLock);
5026 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5027
5028 if (!foundDisplayId) {
5029 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5030 return BAD_VALUE;
5031 }
5032 int32_t displayId = foundDisplayId.value();
5033
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005034 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5035 mTouchStatesByDisplay.find(displayId);
5036 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005037 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5038 return BAD_VALUE;
5039 }
5040
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005041 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00005042 std::optional<int32_t> foundDeviceId;
5043 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005044 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005045 foundDeviceId = state.deviceId;
5046 }
5047 }
5048 if (!foundDeviceId || !state.down) {
5049 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005050 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005051 return BAD_VALUE;
5052 }
5053 int32_t deviceId = foundDeviceId.value();
5054
5055 // Send cancel events to all the input channels we're stealing from.
5056 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005057 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005058 options.deviceId = deviceId;
5059 options.displayId = displayId;
5060 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005061 std::shared_ptr<InputChannel> channel =
5062 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005063 if (channel != nullptr) {
5064 synthesizeCancelationEventsForInputChannelLocked(channel, options);
5065 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005066 }
5067 // Then clear the current touch state so we stop dispatching to them as well.
5068 state.filterNonMonitors();
5069 }
5070 return OK;
5071}
5072
Prabir Pradhan99987712020-11-10 18:43:05 -08005073void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5074 { // acquire lock
5075 std::scoped_lock _l(mLock);
5076 if (DEBUG_FOCUS) {
5077 const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
5078 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5079 windowHandle != nullptr ? windowHandle->getName().c_str()
5080 : "token without window");
5081 }
5082
Vishnu Nairc519ff72021-01-21 08:23:08 -08005083 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005084 if (focusedToken != windowToken) {
5085 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5086 enabled ? "enable" : "disable");
5087 return;
5088 }
5089
5090 if (enabled == mFocusedWindowRequestedPointerCapture) {
5091 ALOGW("Ignoring request to %s Pointer Capture: "
5092 "window has %s requested pointer capture.",
5093 enabled ? "enable" : "disable", enabled ? "already" : "not");
5094 return;
5095 }
5096
5097 mFocusedWindowRequestedPointerCapture = enabled;
5098 setPointerCaptureLocked(enabled);
5099 } // release lock
5100
5101 // Wake the thread to process command entries.
5102 mLooper->wake();
5103}
5104
Michael Wright3dd60e22019-03-27 22:06:44 +00005105std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5106 const sp<IBinder>& token) {
5107 for (const auto& it : mGestureMonitorsByDisplay) {
5108 const std::vector<Monitor>& monitors = it.second;
5109 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005110 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005111 return it.first;
5112 }
5113 }
5114 }
5115 return std::nullopt;
5116}
5117
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005118std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5119 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5120 if (gesturePid.has_value()) {
5121 return gesturePid;
5122 }
5123 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5124}
5125
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005126sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005127 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005128 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005129 }
5130
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005131 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005132 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005133 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005134 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005135 }
5136 }
Robert Carr4e670e52018-08-15 13:26:12 -07005137
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005138 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005139}
5140
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005141std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5142 sp<Connection> connection = getConnectionLocked(connectionToken);
5143 if (connection == nullptr) {
5144 return "<nullptr>";
5145 }
5146 return connection->getInputChannelName();
5147}
5148
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005149void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005150 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005151 removeByValue(mConnectionsByFd, connection);
5152}
5153
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005154void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5155 const sp<Connection>& connection, uint32_t seq,
5156 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005157 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5158 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005159 commandEntry->connection = connection;
5160 commandEntry->eventTime = currentTime;
5161 commandEntry->seq = seq;
5162 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005163 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005164}
5165
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005166void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5167 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005168 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005169 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005170
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005171 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5172 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005173 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005174 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005175}
5176
Vishnu Nairad321cd2020-08-20 16:40:21 -07005177void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5178 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005179 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5180 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005181 commandEntry->oldToken = oldToken;
5182 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005183 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005184}
5185
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005186void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5187 if (connection == nullptr) {
5188 LOG_ALWAYS_FATAL("Caller must check for nullness");
5189 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005190 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5191 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005192 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005193 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005194 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005195 return;
5196 }
5197 /**
5198 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5199 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5200 * has changed. This could cause newer entries to time out before the already dispatched
5201 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5202 * processes the events linearly. So providing information about the oldest entry seems to be
5203 * most useful.
5204 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005205 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005206 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5207 std::string reason =
5208 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005209 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005210 ns2ms(currentWait),
5211 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005212 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005213 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005214
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005215 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5216
5217 // Stop waking up for events on this connection, it is already unresponsive
5218 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005219}
5220
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005221void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5222 std::string reason =
5223 StringPrintf("%s does not have a focused window", application->getName().c_str());
5224 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005225
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005226 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5227 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5228 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005229 postCommandLocked(std::move(commandEntry));
5230}
5231
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005232void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5233 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5234 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5235 commandEntry->obscuringPackage = obscuringPackage;
5236 postCommandLocked(std::move(commandEntry));
5237}
5238
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005239void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
5240 const std::string& reason) {
5241 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5242 updateLastAnrStateLocked(windowLabel, reason);
5243}
5244
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005245void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5246 const std::string& reason) {
5247 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005248 updateLastAnrStateLocked(windowLabel, reason);
5249}
5250
5251void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5252 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005253 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005254 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005255 struct tm tm;
5256 localtime_r(&t, &tm);
5257 char timestr[64];
5258 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005259 mLastAnrState.clear();
5260 mLastAnrState += INDENT "ANR:\n";
5261 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005262 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5263 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005264 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005265}
5266
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005267void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005268 mLock.unlock();
5269
5270 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5271
5272 mLock.lock();
5273}
5274
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005275void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005276 sp<Connection> connection = commandEntry->connection;
5277
5278 if (connection->status != Connection::STATUS_ZOMBIE) {
5279 mLock.unlock();
5280
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005281 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005282
5283 mLock.lock();
5284 }
5285}
5286
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005287void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005288 sp<IBinder> oldToken = commandEntry->oldToken;
5289 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005290 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005291 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005292 mLock.lock();
5293}
5294
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005295void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005296 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005297
5298 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5299
5300 mLock.lock();
5301}
5302
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005303void InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005304 mLock.unlock();
5305
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005306 mPolicy->notifyWindowUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005307
5308 mLock.lock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005309}
5310
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005311void InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005312 mLock.unlock();
5313
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005314 mPolicy->notifyMonitorUnresponsive(commandEntry->pid, commandEntry->reason);
5315
5316 mLock.lock();
5317}
5318
5319void InputDispatcher::doNotifyWindowResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5320 mLock.unlock();
5321
5322 mPolicy->notifyWindowResponsive(commandEntry->connectionToken);
5323
5324 mLock.lock();
5325}
5326
5327void InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5328 mLock.unlock();
5329
5330 mPolicy->notifyMonitorResponsive(commandEntry->pid);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005331
5332 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005333}
5334
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005335void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5336 mLock.unlock();
5337
5338 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5339
5340 mLock.lock();
5341}
5342
Michael Wrightd02c5b62014-02-10 15:10:22 -08005343void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5344 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005345 KeyEntry& entry = *(commandEntry->keyEntry);
5346 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005347
5348 mLock.unlock();
5349
Michael Wright2b3c3302018-03-02 17:19:13 +00005350 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005351 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005352 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005353 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5354 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005355 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005356 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005357
5358 mLock.lock();
5359
5360 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005361 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005362 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005363 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005364 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005365 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5366 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005367 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005368}
5369
chaviwfd6d3512019-03-25 13:23:49 -07005370void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5371 mLock.unlock();
5372 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5373 mLock.lock();
5374}
5375
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005376/**
5377 * Connection is responsive if it has no events in the waitQueue that are older than the
5378 * current time.
5379 */
5380static bool isConnectionResponsive(const Connection& connection) {
5381 const nsecs_t currentTime = now();
5382 for (const DispatchEntry* entry : connection.waitQueue) {
5383 if (entry->timeoutTime < currentTime) {
5384 return false;
5385 }
5386 }
5387 return true;
5388}
5389
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005390void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005391 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005392 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005393 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005394 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005395
5396 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005397 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005398 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005399 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005400 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005401 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005402 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005403 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005404 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5405 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005406 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005407 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005408
5409 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005410 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005411 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005412 restartEvent =
5413 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005414 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005415 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005416 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5417 handled);
5418 } else {
5419 restartEvent = false;
5420 }
5421
5422 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005423 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005424 // contents of the wait queue to have been drained, so we need to double-check
5425 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005426 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5427 if (dispatchEntryIt != connection->waitQueue.end()) {
5428 dispatchEntry = *dispatchEntryIt;
5429 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005430 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5431 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005432 if (!connection->responsive) {
5433 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005434 if (connection->responsive) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005435 // The connection was unresponsive, and now it's responsive.
5436 processConnectionResponsiveLocked(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005437 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005438 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005439 traceWaitQueueLength(connection);
5440 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005441 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005442 traceOutboundQueueLength(connection);
5443 } else {
5444 releaseDispatchEntry(dispatchEntry);
5445 }
5446 }
5447
5448 // Start the next dispatch cycle for this connection.
5449 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005450}
5451
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005452void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
5453 std::unique_ptr<CommandEntry> monitorUnresponsiveCommand = std::make_unique<CommandEntry>(
5454 &InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible);
5455 monitorUnresponsiveCommand->pid = pid;
5456 monitorUnresponsiveCommand->reason = std::move(reason);
5457 postCommandLocked(std::move(monitorUnresponsiveCommand));
5458}
5459
5460void InputDispatcher::sendWindowUnresponsiveCommandLocked(sp<IBinder> connectionToken,
5461 std::string reason) {
5462 std::unique_ptr<CommandEntry> windowUnresponsiveCommand = std::make_unique<CommandEntry>(
5463 &InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible);
5464 windowUnresponsiveCommand->connectionToken = std::move(connectionToken);
5465 windowUnresponsiveCommand->reason = std::move(reason);
5466 postCommandLocked(std::move(windowUnresponsiveCommand));
5467}
5468
5469void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
5470 std::unique_ptr<CommandEntry> monitorResponsiveCommand = std::make_unique<CommandEntry>(
5471 &InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible);
5472 monitorResponsiveCommand->pid = pid;
5473 postCommandLocked(std::move(monitorResponsiveCommand));
5474}
5475
5476void InputDispatcher::sendWindowResponsiveCommandLocked(sp<IBinder> connectionToken) {
5477 std::unique_ptr<CommandEntry> windowResponsiveCommand = std::make_unique<CommandEntry>(
5478 &InputDispatcher::doNotifyWindowResponsiveLockedInterruptible);
5479 windowResponsiveCommand->connectionToken = std::move(connectionToken);
5480 postCommandLocked(std::move(windowResponsiveCommand));
5481}
5482
5483/**
5484 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5485 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5486 * command entry to the command queue.
5487 */
5488void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5489 std::string reason) {
5490 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5491 if (connection.monitor) {
5492 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5493 reason.c_str());
5494 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5495 if (!pid.has_value()) {
5496 ALOGE("Could not find unresponsive monitor for connection %s",
5497 connection.inputChannel->getName().c_str());
5498 return;
5499 }
5500 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5501 return;
5502 }
5503 // If not a monitor, must be a window
5504 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5505 reason.c_str());
5506 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5507}
5508
5509/**
5510 * Tell the policy that a connection has become responsive so that it can stop ANR.
5511 */
5512void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5513 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5514 if (connection.monitor) {
5515 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5516 if (!pid.has_value()) {
5517 ALOGE("Could not find responsive monitor for connection %s",
5518 connection.inputChannel->getName().c_str());
5519 return;
5520 }
5521 sendMonitorResponsiveCommandLocked(pid.value());
5522 return;
5523 }
5524 // If not a monitor, must be a window
5525 sendWindowResponsiveCommandLocked(connectionToken);
5526}
5527
Michael Wrightd02c5b62014-02-10 15:10:22 -08005528bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005529 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005530 KeyEntry& keyEntry, bool handled) {
5531 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005532 if (!handled) {
5533 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005534 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005535 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005536 return false;
5537 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005538
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005539 // Get the fallback key state.
5540 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005541 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005542 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005543 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005544 connection->inputState.removeFallbackKey(originalKeyCode);
5545 }
5546
5547 if (handled || !dispatchEntry->hasForegroundTarget()) {
5548 // If the application handles the original key for which we previously
5549 // generated a fallback or if the window is not a foreground window,
5550 // then cancel the associated fallback key, if any.
5551 if (fallbackKeyCode != -1) {
5552 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005553#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005554 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005555 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005556 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005557#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005558 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005559 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005560
5561 mLock.unlock();
5562
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005563 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005564 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005565
5566 mLock.lock();
5567
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005568 // Cancel the fallback key.
5569 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005570 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005571 "application handled the original non-fallback key "
5572 "or is no longer a foreground target, "
5573 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005574 options.keyCode = fallbackKeyCode;
5575 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005576 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005577 connection->inputState.removeFallbackKey(originalKeyCode);
5578 }
5579 } else {
5580 // If the application did not handle a non-fallback key, first check
5581 // that we are in a good state to perform unhandled key event processing
5582 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005583 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005584 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005585#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005586 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005587 "since this is not an initial down. "
5588 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005589 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005590#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005591 return false;
5592 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005593
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005594 // Dispatch the unhandled key to the policy.
5595#if DEBUG_OUTBOUND_EVENT_DETAILS
5596 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005597 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005598 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005599#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005600 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005601
5602 mLock.unlock();
5603
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005604 bool fallback =
5605 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005606 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005607
5608 mLock.lock();
5609
5610 if (connection->status != Connection::STATUS_NORMAL) {
5611 connection->inputState.removeFallbackKey(originalKeyCode);
5612 return false;
5613 }
5614
5615 // Latch the fallback keycode for this key on an initial down.
5616 // The fallback keycode cannot change at any other point in the lifecycle.
5617 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005618 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005619 fallbackKeyCode = event.getKeyCode();
5620 } else {
5621 fallbackKeyCode = AKEYCODE_UNKNOWN;
5622 }
5623 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5624 }
5625
5626 ALOG_ASSERT(fallbackKeyCode != -1);
5627
5628 // Cancel the fallback key if the policy decides not to send it anymore.
5629 // We will continue to dispatch the key to the policy but we will no
5630 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005631 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5632 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005633#if DEBUG_OUTBOUND_EVENT_DETAILS
5634 if (fallback) {
5635 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005636 "as a fallback for %d, but on the DOWN it had requested "
5637 "to send %d instead. Fallback canceled.",
5638 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005639 } else {
5640 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005641 "but on the DOWN it had requested to send %d. "
5642 "Fallback canceled.",
5643 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005644 }
5645#endif
5646
5647 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5648 "canceling fallback, policy no longer desires it");
5649 options.keyCode = fallbackKeyCode;
5650 synthesizeCancelationEventsForConnectionLocked(connection, options);
5651
5652 fallback = false;
5653 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005654 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005655 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005656 }
5657 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005658
5659#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005660 {
5661 std::string msg;
5662 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5663 connection->inputState.getFallbackKeys();
5664 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005665 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005666 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005667 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005668 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005669 }
5670#endif
5671
5672 if (fallback) {
5673 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005674 keyEntry.eventTime = event.getEventTime();
5675 keyEntry.deviceId = event.getDeviceId();
5676 keyEntry.source = event.getSource();
5677 keyEntry.displayId = event.getDisplayId();
5678 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5679 keyEntry.keyCode = fallbackKeyCode;
5680 keyEntry.scanCode = event.getScanCode();
5681 keyEntry.metaState = event.getMetaState();
5682 keyEntry.repeatCount = event.getRepeatCount();
5683 keyEntry.downTime = event.getDownTime();
5684 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005685
5686#if DEBUG_OUTBOUND_EVENT_DETAILS
5687 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005688 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005689 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005690#endif
5691 return true; // restart the event
5692 } else {
5693#if DEBUG_OUTBOUND_EVENT_DETAILS
5694 ALOGD("Unhandled key event: No fallback key.");
5695#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005696
5697 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005698 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005699 }
5700 }
5701 return false;
5702}
5703
5704bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005705 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005706 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005707 return false;
5708}
5709
5710void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5711 mLock.unlock();
5712
5713 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5714
5715 mLock.lock();
5716}
5717
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005718void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5719 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005720 // TODO Write some statistics about how long we spend waiting.
5721}
5722
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005723/**
5724 * Report the touch event latency to the statsd server.
5725 * Input events are reported for statistics if:
5726 * - This is a touchscreen event
5727 * - InputFilter is not enabled
5728 * - Event is not injected or synthesized
5729 *
5730 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5731 * from getting aggregated with the "old" data.
5732 */
5733void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5734 REQUIRES(mLock) {
5735 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5736 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5737 if (!reportForStatistics) {
5738 return;
5739 }
5740
5741 if (mTouchStatistics.shouldReport()) {
5742 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5743 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5744 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5745 mTouchStatistics.reset();
5746 }
5747 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5748 mTouchStatistics.addValue(latencyMicros);
5749}
5750
Michael Wrightd02c5b62014-02-10 15:10:22 -08005751void InputDispatcher::traceInboundQueueLengthLocked() {
5752 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005753 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005754 }
5755}
5756
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005757void InputDispatcher::traceOutboundQueueLength(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), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005761 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005762 }
5763}
5764
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005765void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005766 if (ATRACE_ENABLED()) {
5767 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005768 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005769 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005770 }
5771}
5772
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005773void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005774 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005775
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005776 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005777 dumpDispatchStateLocked(dump);
5778
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005779 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005780 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005781 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005782 }
5783}
5784
5785void InputDispatcher::monitor() {
5786 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005787 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005788 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005789 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005790}
5791
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005792/**
5793 * Wake up the dispatcher and wait until it processes all events and commands.
5794 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5795 * this method can be safely called from any thread, as long as you've ensured that
5796 * the work you are interested in completing has already been queued.
5797 */
5798bool InputDispatcher::waitForIdle() {
5799 /**
5800 * Timeout should represent the longest possible time that a device might spend processing
5801 * events and commands.
5802 */
5803 constexpr std::chrono::duration TIMEOUT = 100ms;
5804 std::unique_lock lock(mLock);
5805 mLooper->wake();
5806 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5807 return result == std::cv_status::no_timeout;
5808}
5809
Vishnu Naire798b472020-07-23 13:52:21 -07005810/**
5811 * Sets focus to the window identified by the token. This must be called
5812 * after updating any input window handles.
5813 *
5814 * Params:
5815 * request.token - input channel token used to identify the window that should gain focus.
5816 * request.focusedToken - the token that the caller expects currently to be focused. If the
5817 * specified token does not match the currently focused window, this request will be dropped.
5818 * If the specified focused token matches the currently focused window, the call will succeed.
5819 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5820 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5821 * when requesting the focus change. This determines which request gets
5822 * precedence if there is a focus change request from another source such as pointer down.
5823 */
Vishnu Nair958da932020-08-21 17:12:37 -07005824void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5825 { // acquire lock
5826 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005827 std::optional<FocusResolver::FocusChanges> changes =
5828 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
5829 if (changes) {
5830 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07005831 }
5832 } // release lock
5833 // Wake up poll loop since it may need to make new input dispatching choices.
5834 mLooper->wake();
5835}
5836
Vishnu Nairc519ff72021-01-21 08:23:08 -08005837void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
5838 if (changes.oldFocus) {
5839 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005840 if (focusedInputChannel) {
5841 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5842 "focus left window");
5843 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005844 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005845 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005846 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08005847 if (changes.newFocus) {
5848 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005849 }
5850
Prabir Pradhan99987712020-11-10 18:43:05 -08005851 // If a window has pointer capture, then it must have focus. We need to ensure that this
5852 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
5853 // If the window loses focus before it loses pointer capture, then the window can be in a state
5854 // where it has pointer capture but not focus, violating the contract. Therefore we must
5855 // dispatch the pointer capture event before the focus event. Since focus events are added to
5856 // the front of the queue (above), we add the pointer capture event to the front of the queue
5857 // after the focus events are added. This ensures the pointer capture event ends up at the
5858 // front.
5859 disablePointerCaptureForcedLocked();
5860
Vishnu Nairc519ff72021-01-21 08:23:08 -08005861 if (mFocusedDisplayId == changes.displayId) {
5862 notifyFocusChangedLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005863 }
5864}
Vishnu Nair958da932020-08-21 17:12:37 -07005865
Prabir Pradhan99987712020-11-10 18:43:05 -08005866void InputDispatcher::disablePointerCaptureForcedLocked() {
5867 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
5868 return;
5869 }
5870
5871 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
5872
5873 if (mFocusedWindowRequestedPointerCapture) {
5874 mFocusedWindowRequestedPointerCapture = false;
5875 setPointerCaptureLocked(false);
5876 }
5877
5878 if (!mWindowTokenWithPointerCapture) {
5879 // No need to send capture changes because no window has capture.
5880 return;
5881 }
5882
5883 if (mPendingEvent != nullptr) {
5884 // Move the pending event to the front of the queue. This will give the chance
5885 // for the pending event to be dropped if it is a captured event.
5886 mInboundQueue.push_front(mPendingEvent);
5887 mPendingEvent = nullptr;
5888 }
5889
5890 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
5891 false /* hasCapture */);
5892 mInboundQueue.push_front(std::move(entry));
5893}
5894
Prabir Pradhan99987712020-11-10 18:43:05 -08005895void InputDispatcher::setPointerCaptureLocked(bool enabled) {
5896 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5897 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
5898 commandEntry->enabled = enabled;
5899 postCommandLocked(std::move(commandEntry));
5900}
5901
5902void InputDispatcher::doSetPointerCaptureLockedInterruptible(
5903 android::inputdispatcher::CommandEntry* commandEntry) {
5904 mLock.unlock();
5905
5906 mPolicy->setPointerCapture(commandEntry->enabled);
5907
5908 mLock.lock();
5909}
5910
Garfield Tane84e6f92019-08-29 17:28:41 -07005911} // namespace android::inputdispatcher